home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / ASSEMBLE / H235A.ZIP / ASM_0_M.ZIP / HERCBIOS.ASM < prev    next >
Assembly Source File  |  1986-11-22  |  73KB  |  2,460 lines

  1. #!/bin/sh
  2. # shar:    Shell Archiver
  3. #    Run the following text with /bin/sh to create:
  4. #    read.me
  5. #    hercbios.doc
  6. #    hercules.prg
  7. #    gchar.asm
  8. #    graph.asm
  9. #    hcharset.asm
  10. #    hercbios.asm
  11. #    hercbios.aut
  12. #    hercbios.h
  13. #    hercdemo.asm
  14. #    hercmake.att
  15. #    hercmake.lcm
  16. #    hercpixl.dc
  17. #    hercpixl.lc
  18. #    testpix.c
  19. echo x - extracting shar
  20. sed 's/^X//' << 'SHAR_EOF' > read.me
  21. X
  22. X                           H E R C U L E S
  23. X                           ---------------
  24. X
  25. XThis .ARC file contains two sets of information:
  26. X
  27. X
  28. X      - HERCULES.PRG is a memo from Bob Morse and a note from me 
  29. X        explaining the programming parameters for the Hercules (and 
  30. X        clone) graphics board.  His information is especially useful 
  31. X        because he lists the internal parameters which must be 
  32. X        programmed into the 6845 chip to get graphics mode to work 
  33. X        correctly.  Please report any problems with this information to 
  34. X        me at DECWET::BROWN or Bob at LEWS2::MORSE.
  35. X
  36. X        HERCDEMO.COM (source included as HERCDEMO.ASM) is a quick and
  37. X        dirty demo program I wrote to help me understand the way the
  38. X        HERCULES card works, and use graphics character generation.
  39. X
  40. X      
  41. X      - HERCBIOS.COM plus support sofware.  HERCBIOS.COM is a terminate-
  42. X        and-stay-resident program which takes over some functions from 
  43. X        ROM BIOS INT 10h, providing IBM-compatible graphics modes 6 (640 
  44. X        by 200) and 7 (monochrome text) and adding mode 8: Hercules 
  45. X        graphics (720 by 348).  Other functions are just passed through 
  46. X        to the existing ROM BIOS.
  47. X      
  48. X        HERCBIOS was written by Dave Tutelman at AT&T in New Jersey, and 
  49. X        the software came to me via net.micro.pc, hot off the wire two 
  50. X        days ago.  I've included his note and banner as HERCBIOS.AUT.
  51. X      
  52. X        HERCBIOS.DOC explains the operation of the program in detail.
  53. X      
  54. X        HCHARSET.ASM is a simple test program to demonstate IBM and 
  55. X        HERCULES modes.
  56. X      
  57. X        There is also a C program which gives a more extended demo of 
  58. X        the facility:  TESTPIX.C.  TESTPIX must be linked with another C 
  59. X        module, HERCPIXL, which provides the actual linkages to INT 10h.
  60. X        Since system calls are implementation specific, there are two 
  61. X        versions of this module: HERCPIXL.DC and HERCPIXL.LC.  
  62. X        HERCPIXL.DC is DeSmet C compatible and HERCPIXL.LC is Lattice C 
  63. X        compatible.  I've included TESTPIX.EXE (build with Lattice) so 
  64. X        you can test the software if you don't have C.
  65. X      
  66. X        Finally, there are two make files:  HERCMAKE.ATT and 
  67. X        HERCMAKE.LCM.  HERCMAKE.ATT is a make file for a make program 
  68. X        which looks UNIX compatible, so I called it ".ATT".  
  69. X        HERCMAKE.LCM is a make file for the Larry Campbell MAKE program 
  70. X        I use.  In either case, you will have to use the -f switch 
  71. X        invocation of MAKE.  E.g: MAKE -f HERCMAKE.LCM HERCBIOS.COM.
  72. X
  73. X        HERCBIOS.COM seems to work quite nicely as advertised, but I 
  74. X        must warn you that there are some functions which are not yet 
  75. X        implemented -- scrolling in graphics mode, for one.  I'm sure 
  76. X        Dave will continue to enhance it and hope to get future updates.  
  77. X        In the meantime, if anyone gets brave and tackles scrolling, put 
  78. X        the updates on PAR5!
  79. X      
  80. X      
  81. X-Reid Brown
  82. X 6-Sep-1986
  83. X DECWET::BROWN
  84. SHAR_EOF
  85. echo x - extracting shar
  86. sed 's/^X//' << 'SHAR_EOF' > hercbios.doc
  87. X
  88. X
  89. X                             *****   HERCBIOS   *****
  90. X                        BIOS PATCH FOR THE HERCULES BOARD
  91. X
  92. X                               Dave Tutelman  1986
  93. X
  94. X
  95. X
  96. X          The accompanying program is a front end to the INT 10 (VIDEO)
  97. X        functions of the DOS BIOS, so that the important functions work
  98. X        on a Hercules graphics board or its clones. (It was developed on
  99. X        a SuperComputer clone of a Hercules) It is a
  100. X        terminate-and-stay-resident program, that is installed by being
  101. X        called; it is NOT a DOS driver. If you want it installed at boot,
  102. X        include it in AUTOEXEC.BAT, not CONFIG.SYS.
  103. X
  104. X        WHAT IT'S GOOD FOR
  105. X
  106. X        The major strength of this program is that it will allow you to
  107. X        write programs for the Hercules board that run in graphics mode,
  108. X        and still write text easily on the graphics screen. With it, you
  109. X        can program in those higher-level language processors that use
  110. X        the DOS or BIOS calls for display, using their standard I/O calls
  111. X        to write text to the graphics screen. (For a list of known
  112. X        compatible and incompatible languages, see the section later in
  113. X        this manual.)
  114. X
  115. X        A second use of this program is to allow the running of existing
  116. X        graphics programs that use the BIOS calls for ALL screen display.
  117. X        It will NOT allow most commercial graphics programs written for
  118. X        the the Color Graphics Adapter (CGA) to run on the Hercules
  119. X        board. That is because most graphics programs write directly to
  120. X        the video memory instead of using the BIOS calls. The only
  121. X        existing graphics program that this has been tested against is
  122. X        PC-LISP; that is the only graphics program I've encountered that
  123. X        uses the BIOS exclusively.
  124. X
  125. X
  126. X        HOW IT WORKS
  127. X
  128. X        HERCBIOS is a terminate-and-stay-resident program that intercepts
  129. X        all calls to Interrupt 10H, the BIOS video services. It will
  130. X        either process the interrupt or pass the call on to the real
  131. X        BIOS, depending on whether something specific to the Hercules
  132. X        board needs to be done. Specifically, HERCBIOS handles the
  133. X        interrupt itself if (1) the board is in graphics mode, or (2) the
  134. X        BIOS call is a request to enter graphics mode.
  135. X
  136. X        Two graphics modes are recognized and processed by HERCBIOS:
  137. X
  138. X             Mode 6 - IBM Hi-res mode:  This uses part of the 720x348
  139. X             Hercules raster as a 640x200 IBM-compatible graphics screen.
  140. X             It will work with programs for the IBM CGA and its clones,
  141. X             provided they use the BIOS services for their graphics
  142. X             display. (Note - such programs are rare.)
  143. X
  144. X             Mode 8 - Hercules-specific mode:  This uses the full
  145. X
  146. X                                      - 1 -
  147. X
  148. X
  149. X             Hercules raster.
  150. X
  151. X        Actually, both modes are quite capable of putting a pixel
  152. X        anywhere on the Hercules raster.  The major difference is that
  153. X        Mode 6 draws characters in an 8x8 pixel box (like the CGA), while
  154. X        Mode 8 uses the finer resolution of the Hercules board to improve
  155. X        legibility by using a 12x8 pixel box for characters. In either
  156. X        mode, more characters than 25x80 will fit on the screen. Mode 6
  157. X        supports 43x90 characters on the screen (but 25x80 inside the
  158. X        640x200-pixel sub-screen); Mode 8 supports 29x90 characters.
  159. X
  160. X        The functions implemented by HERCBIOS are:
  161. X
  162. X                Fn  0 - Set mode (6, 7, or 8)
  163. X                Fn  2 - Set cursor position
  164. X                Fn  3 - Read cursor position
  165. X                Fn  5 - New display page
  166. X                Fn  9 - Write character with attribute
  167. X                Fn 10 - Write character
  168. X                Fn 12 - Write pixel
  169. X                Fn 13 - Read pixel
  170. X                Fn 14 - Teletypewriter-style character write
  171. X                Fn 15 - Get video status
  172. X
  173. X        Check your System Programmers' Guide for the use of these BIOS
  174. X        functions.
  175. X
  176. X        A number of properties of the alphanumeric display are not
  177. X        supported by the hardware when you enter graphics mode. For
  178. X        instance, the cursor is not shown in graphics mode, nor are all
  179. X        of the character attributes. HERCBIOS does its best to emulate
  180. X        the alphanumeric mode, but it cannot implement a cursor or the
  181. X        blinking or bold attributes. The table below shows the "best
  182. X        shot" that HERCBIOS takes at character attributes:
  183. X
  184. X                CODE    USUALLY MEANS           IBM MODE        HERC MODE
  185. X                00      invisible               invisible       invisible
  186. X                01      underline               [normal]        underline
  187. X                07      normal                  normal          normal
  188. X                0F      hi-intens               [rev video]     [rev video]
  189. X                70      rev video               rev video       rev video
  190. X
  191. X
  192. X                Anything else displays as normal
  193. X
  194. X        The teletypewriter-style output protects the bottom line on the
  195. X        screen as an unscrolled line, for status messages, function key
  196. X        labels, etc. This is non-standard, but I like it. (And we do have
  197. X        more rows than the CGA display. It's the 43rd line that isn't
  198. X        scrolled.)
  199. X
  200. X
  201. X
  202. X
  203. X
  204. X
  205. X
  206. X                                      - 2 -
  207. X
  208. X
  209. X        MAKING AND INSTALLING THE PROGRAM
  210. X        Making the .COM File from Assembler Source
  211. X
  212. X        HERCBIOS was originally developed on ASM 1.0. The version
  213. X        included with this uses MASM 4.0. I don't know for sure whether
  214. X        it will assemble with other versions of assembler.
  215. X
  216. X        The commands for making HERCBIOS.COM from the source are in the
  217. X        MAKEFILE included with the distribution. I run it with NDMAKE, an
  218. X        excellent MS-DOS shareware MAKE from Don Knellers, but it should
  219. X        be easy to adapt to your own favorite MAKE. If you make it by
  220. X        hand, the commands are:
  221. X
  222. X                masm  hercbios;
  223. X                masm  gchar;
  224. X                masm  graph;
  225. X                link  hercbios gchar graph,  hercbios.exe;
  226. X                exe2bin  hercbios.exe hercbios.com
  227. X                del  hercbios.exe
  228. X
  229. X        If you have a machine whose processor is an iAPX 286, 186, or
  230. X        188, you may be able to get some increased performance and a
  231. X        smaller .COM file by editing one character in the header file
  232. X        hercbios.h. Simply remove the ";" that comments out the
  233. X        definition of iAPX286. That will allow some non-8088 instructions
  234. X        to assemble, as well as changing some code that was optimized for
  235. X        speed (at the expense of storage and beauty) on the 8088. (This
  236. X        option is known to assemble and link, but has not been tested; I
  237. X        have no access to a 286 machine with Hercules graphics.)
  238. X
  239. X
  240. X        Installing HERCBIOS.COM
  241. X
  242. X        Once you have HERCBIOS.COM, store it where your PATH will find it
  243. X        and add the line
  244. X
  245. X                HERCBIOS
  246. X
  247. X        to your AUTOEXEC.BAT file somewhere after the PATH command. This
  248. X        will cause it to be installed during boot, so it will be there
  249. X        whenever you run your graphics programs. (Its presence won't
  250. X        affect operation of your computer in alphanumeric mode, since it
  251. X        passes on to the normal BIOS anything that's not in graphics
  252. X        mode.)
  253. X
  254. X        I am including a couple of demonstration/test programs in this
  255. X        distribution, so that you can:
  256. X           - See how to write programs for HERCBIOS.
  257. X           - Test to assure that it runs with your computer and monitor.
  258. X        The programs can be run in their executable form and their source
  259. X        can be examined.
  260. X
  261. X
  262. X
  263. X
  264. X
  265. X
  266. X                                      - 3 -
  267. X
  268. X
  269. X        COMPATIBILITY AND INCOMPATIBILITY
  270. X
  271. X        HERCBIOS has been tested on a Hercules board in an IBM PC-XT, a
  272. X        Hercules-compatible board I built from a SuperComputer bare
  273. X        board, and a Leading Edge XT clone. The current version works
  274. X        with all of these, but I have a homebrew monitor that has trouble
  275. X        syncing to the higher sweep rate of the monochrome display. If
  276. X        you have trouble with the stability of your image, try fiddling
  277. X        with the parameters for the 6845 display chip. They are in the
  278. X        file HERCBIOS.ASM, in the "db" statement defining vid_parm_table
  279. X        at the end of Function 0 (Set Video Mode). I have left in (but
  280. X        commented out) the set of parameters that works on my homebrew
  281. X        monitor.
  282. X
  283. X        I have written programs using HERCBIOS in a number of languages.
  284. X        Here are some of the caveats I'd like to pass on:
  285. X
  286. X          - Things are fine using INT 10h calls in assembler.  (No big
  287. X            surprise.)
  288. X
  289. X          - Turbo Pascal works with HERCBIOS, with one caveat (at least
  290. X            for releases 1 and 2). The Pascal cursor function GoTOXY will
  291. X            home the cursor if presented with x>80 or y>25. To make full
  292. X            use of the 29x90 or 43x90 screen, you will have to write your
  293. X            own version of GoTOXY, using Turbo's machine language escape
  294. X            to issue the INT 10h.
  295. X
  296. X          - I've written a little in Microsoft C 3.0. No problems so far.
  297. X
  298. X          - The TESTPIX program was written in deSmet C 2.4. It worked
  299. X            fine, with one caveat. The console I/O routine getchar()
  300. X            seems to write to display memory (perhaps as part of keyboard
  301. X            echo). This can interfere with what is displayed on the
  302. X            Hercules board display page 1.  (I had no problems on page
  303. X            0.)
  304. X
  305. X          - Forget about using it with BASICA or GWBASIC. Microsoft BASIC
  306. X            graphics routines write directly to display memory,
  307. X            completely bypassing the BIOS.
  308. X
  309. X
  310. X        USE AND ENJOY!
  311. X
  312. X        Bug reports to:
  313. X                            Dave Tutelman
  314. X                            16 Tilton Drive
  315. X                            Wayside, NJ 07712
  316. X
  317. X
  318. X                            Currently receive EMail at ...!mtuxo!mtuxt!dmt
  319. X
  320. X
  321. X        Flames to:
  322. X                            /dev/null
  323. X
  324. X
  325. X
  326. X                                      - 4 -SHAR_EOF
  327. echo x - extracting shar
  328. sed 's/^X//' << 'SHAR_EOF' > hercules.prg
  329. X              Hercules Monochrome Graphics Card Programming
  330. X              ---------------------------------------------
  331. X
  332. X                             provided by
  333. X
  334. X                Robert Morse  MLO5-2/B6  LEWS2::MORSE
  335. X
  336. XThe board configuration is controlled by the write-only control register
  337. Xat port 03BF.  All bits are set to zero upon power-up, which limits
  338. Xthe board to text mode (it will pass IBM monochrome display adapter
  339. Xdiagnostics only while all bits are zero).
  340. X
  341. XBit     Description
  342. X---     -----------
  343. X 0      0=disable setting of graphics mode; 1=allow graphics mode.
  344. X 1      0=disable page one (allows coexistence with a color graphics
  345. X               board); 1=enable page one (required to run Lotus 1-2-3).
  346. X 2..7     (not used)
  347. X
  348. X
  349. X
  350. XModes are controlled by the write-only control register at port 03B8. All
  351. Xbits are set to zero upon power-up. 
  352. X
  353. XBit     Description
  354. X---     -----------
  355. X 0        (not used)
  356. X 1      0=text; 1=graphics.
  357. X 2        (not used)
  358. X 3      0=blank screen; 1=activate screen.
  359. X 4        (not used)
  360. X 5      0=disable text blink; 1=enable text blink.
  361. X 6        (not used)
  362. X 7      0=page zero at B0000h; 1=page one at B8000h.
  363. X
  364. X
  365. X
  366. XTable of 6845 values (all values in hexadecimal): 
  367. X
  368. XRegister                        Text    Graphics
  369. X-------------------------       ----    --------
  370. X 0  Total chars/row -1           61        35    
  371. X 1  Visible chars/row            50        2D
  372. X 2  Hsync position               52        2E
  373. X 3  Hsync width                  0F        07
  374. X 4  Total rows -1                19        5B
  375. X 5  Additional scan lines        06        02
  376. X 6  Visible rows                 19        57
  377. X 7  Vsync position               19        57
  378. X 8  Interlace control            02        02
  379. X 9  Lines/row -1                 0D        03
  380. X A  Top cursor scan              0B        00
  381. X B  Bottom cursor scan           0C        00
  382. X C  Display origin               00        00
  383. X D  Display origin               00        00
  384. XIn text mode, each character time is 0.5625 microseconds and a character is
  385. X9 dots wide and 14 dots high.  The controller is programmed for 25
  386. Xdisplayed rows of 14 scan lines each.  There are 350 visible scan lines and
  387. X370 total scan lines. 
  388. X
  389. X
  390. XIn graphics mode, each character time is 1.000 microseconds and a character
  391. Xis 16 dots wide and 4 dots high.  The controller is programmed for 87
  392. Xdisplayed rows of 4 scan lines each.  There are 348 visible scan lines and
  393. X370 total scan lines.  Each row has 45 displayed characters of 16 bits,
  394. Xgiving 720 dots/row.
  395. X
  396. X
  397. X<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
  398. X                      Note on Addressing the Screen
  399. X                      -----------------------------
  400. X
  401. XThe preceding paragraph gives a hint about pixel addresses in graphics 
  402. Xmode.  I looked through the HERCBIOS sources and then wrote a program
  403. X(HERCDEMO.ASM) to help me understand this.  Here's how screen addressing
  404. Xworks:
  405. X      
  406. X      o Although you might think of graphics mode as pure bits, the 6845
  407. X        chip always thinks in term of characters.  When you switch to
  408. X        graphics mode, the characters are 16 bits wide by 4 bits high.
  409. X        Thus, in graphics mode the screen has 87 rows of "characters"
  410. X        and each row is 45 characters wide, for 720x348 pixels.
  411. X      
  412. X      o For a reason unknown to me (probably speed of memory access),
  413. X        each of the four scan lines in a graphics character is stored in
  414. X        a different "bank" or 2000h section of the screen buffer.  All
  415. X        87 scan line 0s are stored from 0-2000h, all scan line 1s from
  416. X        2000h-4000h, all scan line 2s from 4000h-6000h, and all scan
  417. X        line 3s from 6000h-8000h.
  418. X      
  419. X      o Within a bank of memory (representing one set of scan lines),
  420. X        each row is 45 words or 90 bytes wide.  Rows follow each other
  421. X        with no intervening space. So, assuming row numbers from 0 to
  422. X        86, the 5th graphics character in row 40 is composed of four
  423. X        scan lines, each 16 bits wide, located at the following memory
  424. X        addresses (offsets from the beginning of the screen buffer):
  425. X                40*90 = 3600    (offset in any bank to row 40)
  426. X                4*2=8           (5th graphics char = (n-1)*2 bytes/char)
  427. X                Scan line 0:    locations 3608,3609
  428. X                Scan line 1:    2000h (8192) + 3608,9 = 11800,11801
  429. X                Scan line 3:    4000h (16384) + 3608,9 = 19992,19993
  430. X                Scan line 4:    6000h (24576) + 3608,9 = 28184,28185
  431. X      
  432. X      o Computing a pixel location is a little harder, but still fairly
  433. X        straightforward.  Say you want to address the bit at 300,300
  434. X        with a point of origin at the upper left.  300 scan lines down
  435. X        from the top is 300/4 = 75 (no remainder), which is scan line 0
  436. X        of row 75.  300 bits into the line is 300/8 = 37 remainder 4.
  437. X        The bit you want is in bank 0 (0-2000h) since it is scan line 0,
  438. X        offset by 75*90 =6750 for the row, plus 37 for the byte within
  439. X        the row, or byte offset 6787 from the beginning of that page in
  440. X        screen memory.  Within that byte, you want to set/reset bit 4.
  441. X      
  442. X      
  443. XWell, that should cover it.  If you should discover that I got any of
  444. Xthis wrong, send me mail.
  445. X      
  446. X-Reid Brown
  447. XDECWET::BROWN
  448. SHAR_EOF
  449. echo x - extracting shar
  450. sed 's/^X//' << 'SHAR_EOF' > gchar.asm
  451. X;********************************************************************
  452. X;*
  453. X;*    GRAPHIC CHARACTER HANDLING
  454. X;*
  455. X;*        Dave Tutelman - 8/86
  456. X;*
  457. X;*-------------------------------------------------------------------
  458. X;*
  459. X;*    Fn 6    Scroll up - not yet implemented
  460. X;*    Fn 7    Scroll down - not yet implemented
  461. X;*    Fn 9    Write character with attribute
  462. X;*    Fn 10    Write character normal
  463. X;*    Fn 14    Write character Teletypewriter style
  464. X;*
  465. X;*    Also includes subroutines to:
  466. X;*    get_address    convert page/row/col to display address
  467. X;*    do_char        write a character to an address on display
  468. X;*    do_attrib    change a display address to some attribute
  469. X;*    full_screen_scroll    used by Fn 14, when it needs to scroll
  470. X;*    flash        momentarily flash to reverse video and back
  471. X;*
  472. X;********************************************************************
  473. X;
  474. XINCLUDE    hercbios.h
  475. X
  476. X;-----------------------------------------------
  477. Xextrn    exit_herc_bios:near
  478. Xpublic    writechar,scroll_up,scroll_down,tty
  479. Xpublic    scr_start,scr_length,num_rows
  480. X;------------------------------------
  481. Xcseg    segment    public
  482. X    assume    cs:cseg,ds:bios_data
  483. X;
  484. X
  485. X;**************************************************************
  486. X;*
  487. X;*    FUNCTION 6 & 7 - SCROLL UP & DOWN
  488. X;*    (Placeholder only - not yet implemented)
  489. X;*
  490. X;*    AL = Number of rows to scroll (if 0, blank scroll area)
  491. X;*    BH = Fill attribute (we ignore, since writechar destroys old attrib)
  492. X;*    CX = Upper left corner      (CH=row, CL=col)
  493. X;*    DX = Lower right corner     (DH=row, DL=col)
  494. X;*
  495. X;****************************************************************
  496. X;
  497. Xscroll_up:
  498. Xscroll_down:
  499. X;
  500. X    jmp    exit_herc_bios
  501. Xpage
  502. X;********************************************************************
  503. X;*
  504. X;*    FUNCTION 9 & 10 - WRITE A CHARACTER AT CURRENT CURSOR
  505. X;*
  506. X;*    AL = character code to be written
  507. X;*    AH = 9 (write char with attribute) or 10 (write char normal)
  508. X;*    BL = new attribute (limited selection in graphics mode)
  509. X;*    BH = display page number
  510. X;*    CX = count of how many characters to write
  511. X;*
  512. X;********************************************************************
  513. X;
  514. Xwritechar:    
  515. X;            ; Get the address corresponding to cursor[page]
  516. X    push    bx
  517. X    mov    bl,bh        ; page to BX
  518. X    xor    bh,bh
  519. X    shl    bx,1        ; *2 for word pointer
  520. X    mov    dx,curs_pos[bx]    ; appropriate cursor position to DX
  521. X    pop    bx
  522. X    call    get_address    ; get display address in DI
  523. X;
  524. Xwrchar_loop:
  525. X;            ; Write a character to that address
  526. X    call    do_char        ; arguments set up already
  527. X;
  528. X;            ; If function 9, modify the character's attributes
  529. X    cmp    ah,9        ; Function 9?
  530. X    jne    no_attrib    ; no, don't do attributes
  531. X    call    do_attrib    ; yes, and arguments already set up
  532. Xno_attrib:
  533. X;
  534. X    inc    di        ; move to next position, without moving
  535. X                ;    the official cursor
  536. X    loop    wrchar_loop    ; continue until CX count exhausted
  537. X    jmp    exit_herc_bios
  538. Xpage
  539. X;*****************************************************************
  540. X;*
  541. X;*    FUNCTION 14 - TELETYPEWRITER-STYLE CHARACTER WRITE
  542. X;*
  543. X;*    AL = Character to be written
  544. X;*
  545. X;******************************************************************
  546. X;
  547. Xtty:
  548. X    assume    ds:bios_data
  549. X    mov    bl,active_page    ; active page to BX
  550. X    xor    bh,bh
  551. X    mov    dx,curs_pos[bx]    ; get cursor for active page
  552. X    push    bx
  553. X    mov    bh,bl        ; move page to BH
  554. X    call    get_address    ; address of character to DI
  555. X    pop    bx
  556. X;
  557. X;            ; process the character
  558. X;            ; check if CR
  559. X    cmp    al,13        ; carriage return?
  560. X    jne    not_cr
  561. X    mov    dl,0        ; go to first column
  562. X    jmp    fix_curs
  563. X;            ; check if LF
  564. Xnot_cr:    cmp    al,10        ; line feed?
  565. X    jne    not_lf
  566. X    inc    dh        ; next line
  567. X    jmp    fix_curs
  568. X;            ; check if BS
  569. Xnot_lf:    cmp    al,8        ; backspace?
  570. X    jne    not_bs
  571. X    cmp    dl,0        ; already first column?
  572. X    je    fix_curs    ; yup. do nothing
  573. X    dec    dl        ; nope. move cursor left one
  574. X    dec    di        ; also move address pointer left one
  575. X    mov    al,32        ; set character to space
  576. X    call    do_char        ; and write the space, but don't move
  577. X    jmp    fix_curs
  578. X;            ; check if BEL
  579. Xnot_bs:    cmp    al,7        ; bell character?
  580. X    jne    not_bl
  581. X    pop    es        ; restore registers
  582. X    pop    di
  583. X    pop    si
  584. X    pop    dx
  585. X    pop    cx
  586. X    pop    bx
  587. X    pop    ds
  588. X    jmp    vid_bios    ; ... and use the normal BIOS to ring the bell
  589. X;    call    flash        ; can't do BEL standard. Blink display instead
  590. X;    jmp    fix_curs
  591. X;            ; ordinary printing character, so display it
  592. Xnot_bl:    call    do_char        ; write it to screen
  593. X    inc    dl        ; cursor one to the right
  594. X;
  595. X;            ; now look at the cursor, do what's necessary to
  596. X;            ; fix it up, and save it away.
  597. Xfix_curs:
  598. X    cmp    dl,89        ; beyond last column?
  599. X    jle    chk_scroll    ; not yet
  600. X    xor    dl,dl        ; yes. do a CR
  601. X    inc    dh        ; ... and a LF
  602. Xchk_scroll:
  603. X    cmp    dh,cs:num_rows    ; now see if we're beyond last row?
  604. X    jl    exit_tty    ; not yet
  605. X    call    full_screen_scroll
  606. X                ; yes. Scroll the screen up one
  607. X    dec    dh        ; ... and scroll cursor, too.
  608. X    jmp    chk_scroll
  609. X;
  610. Xexit_tty:
  611. X    mov    curs_pos[bx],dx    ; save cursor position
  612. X    jmp    exit_herc_bios
  613. Xpage
  614. X;--------------------------------------------------------------------
  615. X;
  616. X;    GET_ADDRESS  SUBROUTINE
  617. X;
  618. X;    BH = display page
  619. X;    DX = cursor position (DH=row, DL=col)
  620. X;
  621. X;    returns:
  622. X;    DI = displacement of top row of pixels
  623. X;
  624. X;--------------------------------------------------------------------
  625. X;
  626. Xget_address:
  627. X    push    cx        ; save it
  628. X
  629. X;            ; compute display address from cursor_pos
  630. X    mov    cl,dh        ; get row # in cx
  631. X    xor    ch,ch
  632. X    shl    cx,1        ; begin fast multiply by 90 (1011010 B)
  633. X    mov    di,cx
  634. X    shl    cx,1
  635. X    shl    cx,1
  636. X    add    di,cx
  637. X    shl    cx,1
  638. X    add    di,cx
  639. X    shl    cx,1
  640. X    shl    cx,1
  641. X    add    di,cx        ; end fast multiply by 90
  642. X    mov    cx,di        ; copy answer back to cx
  643. X    shl    di,1        ; *2 for ibm graphics mode
  644. X    cmp    video_mode,herc_mode
  645. X    jne    ibm_ad        ; not herc mode
  646. X    add    di,cx        ; *3 for herc mode
  647. Xibm_ad:    xor    ch,ch        ; columns in CX
  648. X    mov    cl,dl
  649. X    add    di,cx        ; add in col. address in DI
  650. X    cmp    bh,0        ; if page 1, set high-order bit of address
  651. X    je    pg0
  652. X    or    di,8000H
  653. Xpg0:
  654. X;            ; address now in DI
  655. X;
  656. X    pop    cx        ; restore it
  657. X    ret
  658. Xpage
  659. X;--------------------------------------------------------------------
  660. X;
  661. X;    DO_CHAR  SUBROUTINE
  662. X;
  663. X;    AL = character to write
  664. X;    DI = diplacement (address) of top row of pixels
  665. X;
  666. X;    Note: SI and ES are destroyed
  667. X;
  668. X;--------------------------------------------------------------------
  669. X;
  670. Xdo_char:
  671. X    push    ax
  672. X    push    bx
  673. X    push    cx
  674. X    push    di
  675. X    push    ds
  676. X;
  677. X;            ; get scan pattern table pointer into BX
  678. X    cmp    video_mode,herc_mode
  679. X    je    herc_1
  680. X    mov    bx,offset ibm_pattern
  681. X                ; IBM graphics mode - use appropriate table
  682. X    jmp    c_1
  683. Xherc_1:    mov    bx,offset herc_pattern
  684. X                ; herc graphics mode - use appropriate table
  685. Xc_1:
  686. X;
  687. X;            ; set up source address registers
  688. X    xor    ah,ah        ; character to SI
  689. X    mov    si,ax
  690. XIFDEF iAPX286
  691. X    shl    si,3        ; *8 for 8-byte table entry
  692. XELSE
  693. X    shl    si,1        ; *8 for 8-byte table entry
  694. X    shl    si,1
  695. X    shl    si,1
  696. XENDIF
  697. X                ; next, find beginning of table
  698. X    cmp    al,7Fh        ; ROM or user table?
  699. X    jg    u_tbl
  700. X                ; ROM table
  701. X    add    si,charbase    ; character table base added to offset
  702. X    mov    ax,mpx_bios    ; BIOS code segment to DS
  703. X    mov    ds,ax
  704. X    jmp    c_2
  705. Xu_tbl:                ; user table
  706. X    xor    ax,ax        ; zero (interrupt vector) to DS
  707. X    mov    ds,ax
  708. X    mov    ax,si        ; save table offset in AX
  709. X    assume    ds:intvec
  710. X    lds    si,user_table    ; load DS:SI from interrupt vector
  711. X    add    si,ax        ; add offset into table base
  712. Xc_2:
  713. X;
  714. X;            ; set up destination address registers
  715. X    mov    ax,pixbase    ; get display segment in ES
  716. X    mov    es,ax
  717. X                ; displacement already in DI
  718. X;
  719. X;
  720. X;            ; transfer the character
  721. X    mov    ax,di        ; save top-row displacement in AX
  722. X    mov    cx,8        ; transfer 8 rows
  723. X    cld            ; direction = up
  724. Xc_loop:    mov    di,ax        ; top-row displacement
  725. X    add    di,cs:[bx]    ; add entry from scan-pattern table
  726. X    movsb            ; actually transfer a byte and bump SI & DI
  727. X    add    bx,2        ; next entry in scan-pattern table
  728. X    loop    c_loop
  729. X;
  730. X;            ; if hercules mode, blank the extra rows
  731. X    pop    ds        ; restore DS to Bios data
  732. X    assume    ds:bios_data
  733. X    cmp    video_mode,herc_mode
  734. X    jne    c_3
  735. X                ; Hercules mode
  736. X    mov    si,ax        ; don't need SI. Save top-row displacement
  737. X    xor    ax,ax        ; zero AX
  738. X    mov    cx,4        ; four rows to blank
  739. X    cld
  740. Xc_blnk: mov    di,si        ; top-row displacement
  741. X    add    di,cs:[bx]    ; add entry from scan-pattern table
  742. X    stosb            ; transfer a zero byte
  743. X    add    bx,2        ; next entry in scan-pattern table
  744. X    loop    c_blnk
  745. Xc_3:
  746. X;
  747. X;            ; clean up and return
  748. X    pop    di
  749. X    pop    cx
  750. X    pop    bx
  751. X    pop    ax
  752. X    ret
  753. Xpage
  754. X;---------------------------------------------------------------------
  755. X;
  756. X;    DO_ATTRIB  SUBROUTINE
  757. X;
  758. X;    BL = attribute byte
  759. X;    DI = displacement (address) of top row of pixels
  760. X;    ES is destroyed
  761. X;
  762. X;    Because attributes don't "just happen" in graphics mode, here's
  763. X;    what we have to transform them to.
  764. X;
  765. X;    CODE    USUALLY MEANS        IBM MODE    HERC MODE
  766. X;    00    invisible        invisible    invisible
  767. X;    01    underline        [normal]    underline
  768. X;    07    normal            normal        normal
  769. X;    0F    hi-intens        [rev video]    [rev video]
  770. X;    70    rev video        rev video    rev video
  771. X;
  772. X;    Anything else displays as normal
  773. X;    Note that there's no way to make blinking happen.
  774. X;
  775. X;-----------------------------------------------------------------------
  776. X;
  777. Xdo_attrib:
  778. X    assume    ds:bios_data
  779. X    push    ax
  780. X    mov    ax,pixbase    ; Display base to ES
  781. X    mov    es,ax
  782. X    pop    ax
  783. X;
  784. X;            ; which attribute, if any?
  785. X    and    bl,7Fh        ; mask off blink bit
  786. X    cmp    bl,0        ; invisible?
  787. X    je    invisible
  788. X    cmp    bl,0Fh        ; reverse video? (instead of bright)
  789. X    je    reverse
  790. X    cmp    bl,70H        ; reverse video?
  791. X    je    reverse
  792. X    cmp    bl,01        ; underline?
  793. X    je    underline
  794. X    ret            ; none of the above. Display normal.
  795. X;
  796. X;            ; underline the character
  797. Xunderline:
  798. X    cmp    video_mode,herc_mode
  799. X    je    ul_1
  800. X    ret            ; don't do it for IBM mode
  801. Xul_1:    mov    byte ptr es:[di+40B4h],0FFh
  802. X                ; move ones to 11th line of pixel array
  803. X                ; 40B4h is the 11th entry in herc_pattern
  804. X    ret
  805. X;
  806. X;            ; make it invisible
  807. Xinvisible:
  808. X    push    ax
  809. X    push    bx
  810. X    push    cx
  811. X    push    dx
  812. X    xor    ax,ax        ; zero the AX
  813. X    cmp    video_mode,herc_mode
  814. X    je    herc_3
  815. X    mov    bx,offset ibm_pattern
  816. X                ; point to scan pattern
  817. X    jmp    inv_1
  818. Xherc_3:    mov    bx,offset herc_pattern
  819. X                ; point to scan pattern
  820. Xinv_1:    mov    dx,di        ; save addr of top row of pixels in DX
  821. X    mov    cx,8        ; 8 bytes to be moved
  822. X    cld            ; direction = up
  823. Xinvis_loop:
  824. X    mov    di,dx        ; top row address
  825. X    add    di,cs:[bx]    ; add scan-table offset
  826. X    stosb            ; move a zero byte
  827. X    add    bx,2        ; bump the scan-table pointer
  828. X    loop    invis_loop
  829. X    pop    dx
  830. X    pop    cx
  831. X    pop    bx
  832. X    pop     ax
  833. X    ret
  834. X;
  835. X;            ; reverse video
  836. Xreverse:
  837. X    push    bx
  838. X    push    cx
  839. X    push    dx
  840. X    cmp    video_mode,herc_mode
  841. X    je    herc_4
  842. X    mov    bx,offset ibm_pattern
  843. X                ; point to scan pattern
  844. X    mov    cx,8        ; 8 scan lines for IBM mode
  845. X    jmp    rev_1
  846. Xherc_4:    mov    bx,offset herc_pattern
  847. X                ; point to scan pattern
  848. X    mov    cx,12        ; 12 scan lines for Hercules mode
  849. Xrev_1:    mov    dx,di        ; save addr of top row of pixels in DX
  850. X    cld            ; direction = up
  851. Xrev_loop:
  852. X    mov    di,dx        ; top row address
  853. X    add    di,cs:[bx]    ; add scan-table offset
  854. X    not    es:byte ptr[di]    ; invert one scan line
  855. X    add    bx,2        ; bump the scan-table pointer
  856. X    loop    rev_loop
  857. X    pop    dx
  858. X    pop    cx
  859. X    pop    bx
  860. X    ret
  861. Xpage
  862. X;--------------------------------------------------------------
  863. X;
  864. X;    SUBROUTINE  FULL_SCREEN_SCROLL
  865. X;
  866. X;    This scrolls the entire screen up one print line (8 or 12 pixels).
  867. X;    Actually, we'll protect one line on the bottom (e.g.-function keys).
  868. X;
  869. X;-----------------------------------------------------------------
  870. X;
  871. X;            ; A few constants, initialized by set_mode
  872. Xnum_rows    db    ?    ; number of rows in display
  873. X                ;   = 42 (IBM)  or 28 (Herc)
  874. Xscr_start    dw    ?    ; 2*90 or 3*90 depending on mode
  875. Xscr_length    dw    ?    ; number of words to transfer in a sweep
  876. X                ;   = 41*start /2 = 3690    (IBM)
  877. X                ;   = 27*start /2 = 3645    (Herc)
  878. X;
  879. Xfull_screen_scroll:
  880. X    assume    ds:bios_data
  881. X    push    ds
  882. X    push    ax
  883. X    push    cx
  884. X    mov    ax,pixbase    ; start getting display segment
  885. X    cmp    active_page,0    ; page 0?
  886. X    je    scr_pg0        
  887. X    add    ax,800H        ; page 1. bump by half of 64K
  888. Xscr_pg0:
  889. X    mov    ds,ax        ; save display segment in DS
  890. X    mov    es,ax        ; ... and in ES
  891. X;
  892. X    xor    ax,ax        ; zero AX
  893. X    call    scr_shift
  894. X    mov    ax,2000H    ; bump interlace counter
  895. X    call    scr_shift
  896. X    mov    ax,4000H
  897. X    call    scr_shift
  898. X    mov    ax,6000H
  899. X    call    scr_shift
  900. X;
  901. X    pop    cx
  902. X    pop    ax
  903. X    pop    ds
  904. X    ret
  905. X;
  906. X;
  907. X; scr_shift does the actual work of scrolling, one set of interlace
  908. X;   lines at a time.
  909. X;
  910. Xscr_shift:
  911. X    cld            ; block moves will be UP
  912. X    mov    di,ax        ; interlace scan ID to DI
  913. X    mov    si,ax        ; ... and to SI
  914. X    add    si,cs:scr_start
  915. X                ; but bump by "start"
  916. X    mov    cx,cs:scr_length
  917. X                ; set counter for transfer
  918. X    rep    movsw        ; and scroll a set of lines
  919. X    xor    ax,ax        ; set up a zero word
  920. X    mov    cx,cs:scr_start ; set counter for one more line
  921. X    shr    cx,1        ; /2 for word transfers
  922. X    rep    stosw        ; and blank the line
  923. X    ret
  924. Xpage
  925. X;-----------------------------------------------------------
  926. X;
  927. X;    SUBROUTINE FLASH
  928. X;
  929. X;    Flashes the screen inverse video and back to normal.
  930. X;    Used in place of an audible bell.
  931. X;
  932. X;-------------------------------------------------------------
  933. X;
  934. Xflash:
  935. X    push    cx
  936. X    push    di
  937. X    push    es
  938. X;
  939. X    mov    di,pixbase    ; get display area base
  940. X    cmp    active_page,0    ; page 0?
  941. X    je    pg0_f
  942. X    add    di,800H        ; no, page 1
  943. Xpg0_f:    mov    es,di        ; put resulting pointer to display in ES
  944. X;
  945. X;            ; loop to invert screen
  946. X    xor    di,di        ; point to beginning of display area
  947. X    mov    cx,4000H    ; number of words to invert
  948. Xflash_loop_1:
  949. X    not    word ptr es:[di]
  950. X                ; invert one location
  951. X    add    di,2        ; bump location pointer a word
  952. X    loop    flash_loop_1
  953. X;
  954. X;            ; and invert it back to normal
  955. X    xor    di,di        ; point to beginning of display area
  956. X    mov    cx,4000H    ; number of words to invert
  957. Xflash_loop_2:
  958. X    not    word ptr es:[di]
  959. X                ; invert one location
  960. X    add    di,2        ; bump location pointer a word
  961. X    loop    flash_loop_2
  962. X;
  963. X    pop    es
  964. X    pop    di
  965. X    pop    cx
  966. X    ret
  967. Xpage
  968. X;*****************************************************
  969. X;*    Data areas for character handling
  970. X;*****************************************************
  971. X;
  972. Xpixels        db    12 dup(?)    ; 12 bytes for pixel pattern
  973. Xibm_pattern    dw    0000h,2000h,4000h,6000h,005Ah,205Ah,405Ah,605Ah
  974. Xherc_pattern    dw    4000h,6000h,005Ah,205Ah,405Ah,605Ah,00B4h,20B4h
  975. Xblank_pattern    dw    0000h,2000h,40B4h,60B4h
  976. X;
  977. X;
  978. Xcseg    ends
  979. X    end
  980. SHAR_EOF
  981. echo x - extracting shar
  982. sed 's/^X//' << 'SHAR_EOF' > graph.asm
  983. X;*******************************************************
  984. X;*    
  985. X;*    SET OF GRAPHICS ROUTINES FOR HERCULES BIOS
  986. X;*
  987. X;*        Dave Tutelman - 8/86
  988. X;*
  989. X;*-------------------------------------------------------
  990. X;*
  991. X;*    do_pixel:    draws, erases, or reads a pixel, given an
  992. X;*            offset and mask.
  993. X;*
  994. X;**********************************************************
  995. X;
  996. XINCLUDE    hercbios.h
  997. X
  998. X;------------------------------------------
  999. Xpublic    wr_pixel,end_herc
  1000. Xextrn    exit_herc_bios:near
  1001. X;-----------------------------------------
  1002. X;
  1003. Xcseg    segment    public
  1004. X    assume    cs:cseg,ds:bios_data
  1005. X;
  1006. X;
  1007. X;**********************************************
  1008. X;*
  1009. X;*    read or write a pixel:
  1010. X;*        DX = row # ( y )
  1011. X;*        CX = col # ( x )
  1012. X;*        AH = 12 for write, 13 for read
  1013. X;*        AL = value (0,1, if bit 7=1 EXOR the value)
  1014. X;*
  1015. X;**********************************************
  1016. X;
  1017. Xwr_pixel:
  1018. X    mov    bh,video_mode    ; check for valid mode
  1019. X    cmp    bh,herc_mode
  1020. X    je    do_pixel
  1021. X    cmp    bh,ibm_mode
  1022. X    je    do_pixel
  1023. X    jmp    exit_herc_bios        ; invalid mode. don't do it.
  1024. X;
  1025. Xdo_pixel:
  1026. X    push    ax        ; save function and pixel value
  1027. X;
  1028. X;            ; first compute the address of byte to be modified
  1029. X;            ; = 90*[row/4] + [col/8] + 2^D*[row/4] + 2^F*page
  1030. X    mov    bh,cl        ; col (low order) in BH
  1031. X    mov    bl,dl        ; row (low order) in BL
  1032. X    and    bx,0703H    ; mask the col & row remainders
  1033. XIFDEF iAPX286
  1034. X    shr    cx,3        ; col / 8
  1035. X    shr    dx,2        ; row / 4
  1036. X    mov    al,90
  1037. X    mul    dx        ; AX = 90*[ row/4 ]
  1038. X    add    ax,cx        ;  ... + col/8
  1039. X    shl    bl,5        ; align row remainder
  1040. XELSE            ; same as above, obscure but fast for 8086
  1041. X    shr    cx,1        ; divide col by 8
  1042. X    shr    cx,1
  1043. X    shr    cx,1
  1044. X    shr    dx,1        ; divide row by 4
  1045. X    shr    dx,1
  1046. X    shl    dx,1        ; begin fast multiply by 90 (1011010 B)
  1047. X    mov    ax,dx
  1048. X    shl    dx,1
  1049. X    shl    dx,1
  1050. X    add    ax,dx
  1051. X    shl    dx,1
  1052. X    add    ax,dx
  1053. X    shl    dx,1
  1054. X    shl    dx,1
  1055. X    add    ax,dx        ; end fast multiply by 90
  1056. X    add    ax,cx        ; add on the col/8
  1057. X    shl    bl,1        ; align row remainder
  1058. X    shl    bl,1
  1059. X    shl    bl,1
  1060. X    shl    bl,1
  1061. X    shl    bl,1
  1062. XENDIF
  1063. X    add    ah,bl        ; use aligned row remainder
  1064. X    cmp    active_page,0    ; page 0 active?
  1065. X    je    end_adr_calc    ; yup
  1066. X    or    ah,80H        ; page 1 active. Set MSB of address
  1067. Xend_adr_calc:        ; address of byte is now in AX
  1068. X;
  1069. X    mov    dx,pixbase    ; base of pixel display to DX
  1070. X    mov    es,dx        ; ...and thence to segment reg
  1071. X    mov    si,ax        ; address of byte w/ pixel to index reg
  1072. X    mov    cl,bh        ; bit addr in byte
  1073. X    mov    al,80H        ; '1000 0000' in AL 
  1074. X    shr    al,cl        ; shift mask to line up with bit to read/write
  1075. X    mov    bl,al    
  1076. X;
  1077. X    pop    bx        ; now retrieve original AX into BX
  1078. X                ;      function=BH, pixel value=BL
  1079. X    cmp    bh,13        ; what to do with the pixel?
  1080. X    je    read_pix    ; read the pixel.
  1081. X    cmp    bl,0        ; write the pixel. But how?
  1082. X    je    clr_pix        ; clear the pixel
  1083. X    jl    exor_pix    ; exclusive-or the pixel
  1084. X;
  1085. Xset_pix:        ; set the pixel
  1086. X    or    es:[si],al    ; or the mask with the right byte
  1087. X    jmp    exit_herc_bios
  1088. X;
  1089. Xclr_pix:        ;clear the pixel
  1090. X    not    al        ; invert the mask, so zero on bit to be cleared
  1091. X    and    es:[si],al    ; and the mask with the right byte
  1092. X    jmp    exit_herc_bios
  1093. X;
  1094. Xexor_pix:        ; exclusive-or the pixel
  1095. X    mov    ah,07fH        ; mask to rid 7th bit
  1096. X    and    ah,bl        ; pixval w/o XOR flag
  1097. X    jnz    do_exor        ; ExOr with a 1?
  1098. X    jmp    exit_herc_bios    ; no! XOR (0,x) = x. just return.
  1099. Xdo_exor:
  1100. X    xor    es:[si],al    ; EXOR the pixel with the mask.
  1101. X    jmp    exit_herc_bios
  1102. X;
  1103. Xread_pix:        ; read the pixel
  1104. X    and    al,es:[si]    ; read the bit into AL
  1105. X    jz    rd_zro
  1106. X    mov    al,1        ; if it ain't zero, it's one
  1107. Xrd_zro:    jmp    exit_herc_bios
  1108. X;
  1109. X;
  1110. Xend_herc:            ; label for end of package. Used by hercbios
  1111. X                ;    to install it.
  1112. X;
  1113. Xcseg    ends
  1114. X    end
  1115. SHAR_EOF
  1116. echo x - extracting shar
  1117. sed 's/^X//' << 'SHAR_EOF' > hcharset.asm
  1118. X;**************************************************************
  1119. X;*
  1120. X;*    Tests Hercules BIOS, specifically the functions 9 & 10
  1121. X;*    to put characters on the screen in graphics mode.
  1122. X;*
  1123. X;***************************************************************
  1124. XVIDI    equ    10H        ; video interrupt, 10H (50H for debug)
  1125. Xcseg    segment    common
  1126. X    assume    cs:cseg,ds:cseg
  1127. XSTART    proc
  1128. X;            ; prompt for IBM or Hercules graphics mode
  1129. X    mov    ah,9        ; DOS 9 = display string
  1130. X    mov    dx,offset mode_prmt+100H
  1131. X                ; display mode prompt
  1132. X    int    21H        ; DOS function
  1133. X    mov    ah,1        ; DOS 1 = kbd input
  1134. X    int    21H
  1135. X    mov    bl,al        ; input char --> BL
  1136. X    mov    ax,6        ; ibm graphics mode
  1137. X    cmp    bl,"h"        ; input "h" for Hercules
  1138. X    jne    i_mode
  1139. X    add    ax,2        ; hercules mode
  1140. Xi_mode:    int    VIDI
  1141. X;
  1142. X    xor    bh,bh        ; page 0
  1143. X    mov    bl,7        ; normal attribute
  1144. X    mov    dh,1        ; cursor at <1,1> to start
  1145. X    mov    dl,1
  1146. X;
  1147. X    mov    cx,24        ; do 24 rows
  1148. Xrow:    push    cx        ; save row counter
  1149. X    inc    dh        ; next row
  1150. X    mov    dl,0        ; back to first column
  1151. X    mov    ah,2        ; cursor move function
  1152. X    int    VIDI
  1153. X;            ; compute video mode
  1154. X    mov    bl,dh        ; row # to BL
  1155. X    xor    bh,bh
  1156. X    shr    bl,1        ; 4 rows per mode
  1157. X    shr    bl,1
  1158. X    mov    bl,mode_seq[bx+100H]    ; index into mode sequence for mode
  1159. X;
  1160. X;            ; for debug, first print [row+64]
  1161. X    mov    al,dh
  1162. X    add    al,64
  1163. X    mov    ah,10        ; fn 10 prints w/o attributes
  1164. X    mov    cx,1
  1165. X    int    VIDI
  1166. X;
  1167. X    xor    bh,bh        ; page 0
  1168. X    mov    cx,64        ; each row 64 characters
  1169. Xachar:    push    cx        ; save char counter
  1170. X    mov    ah,9        ; write_char function
  1171. X    mov    al,dh        ; character = col + (row mod 2)*64
  1172. X    and    al,1        ; row mod 2
  1173. X    ror    al,1        ; *128
  1174. X    shr    al,1
  1175. X    add    al,dl        ; + col
  1176. X    mov    cx,1        ; write one of them
  1177. X    int    VIDI
  1178. X    inc    dl        ; increment row counter
  1179. X    mov    ah,2        ; cursor move function
  1180. X    int    VIDI
  1181. X    pop    cx        ; restore character counter
  1182. X    loop    achar
  1183. X    pop    cx        ; restore row counter
  1184. X    loop    row
  1185. X;
  1186. X;            ; draw a line where it should start
  1187. X    mov    dx,5        ; row 5
  1188. X    mov    cx,0        ; col 0
  1189. Xline:    push    cx
  1190. X    push    dx
  1191. X    mov    ax,0C01H    ; function 12=pixel
  1192. X    int     VIDI
  1193. X    pop    dx
  1194. X    pop    cx
  1195. X    inc    cx        ; step col
  1196. X    cmp    cx,700        ; ...until 700
  1197. X    jle    line
  1198. X;
  1199. X;            ; wait for a keystroke
  1200. X    mov    ah,1
  1201. X    int    21H
  1202. X;
  1203. X    mov    ax,7        ; back to alpha mode
  1204. X    int     VIDI
  1205. X;
  1206. X;              ; Now return to system
  1207. X    xor    ax,ax        ; zero --> AX
  1208. X    int    21H        ; DOS function call 0 - terminate normally
  1209. X;
  1210. Xmode_prmt    db    "hercules or ibm mode? [ibm] $"
  1211. Xmode_seq    db    7,0Fh,1,70h,0,9    ; sequence norm,hi,ul,rev,invis,norm
  1212. XSTART    endp
  1213. Xcseg    ends
  1214. X        end     START
  1215. SHAR_EOF
  1216. echo x - extracting shar
  1217. sed 's/^X//' << 'SHAR_EOF' > hercbios.asm
  1218. X;*******************************************************
  1219. X;*
  1220. X;*    Main program file for HERCBIOS
  1221. X;*
  1222. X;*        Dave Tutelman - 8/86
  1223. X;*
  1224. X;*------------------------------------------------------
  1225. X;*    
  1226. X;*    INT10 -- acts as pre-handler for video interrupts
  1227. X;*    (BIOS calls) for Hercules & SuperComputer
  1228. X;*    monochrome graphics board.  Calls real BIOS
  1229. X;*    if not a Hercules special. Handled here are:
  1230. X;*
  1231. X;*    Fn 0    Set mode (only 6 & 8)
  1232. X;*    and all functions, when in mode 6 or 8.
  1233. X;*    Actually, we've only implemented:
  1234. X;*    Fn 2    Set cursor position
  1235. X;*    Fn 3    Read cursor position
  1236. X;*    Fn 5    New display page
  1237. X;*    Fn 9    Write character with attribute
  1238. X;*    Fn 10    Write character
  1239. X;*    Fn 12    Write pixel
  1240. X;*    Fn 13    Read pixel
  1241. X;*    Fn 14    Teletypewriter-style character write
  1242. X;*    Fn 15    Get video status
  1243. X;*
  1244. X;*    The only allowable modes for these boards are:
  1245. X;*    6    IBM graphics (we handle it, but poor aspect ratio).
  1246. X;*    7    Monochrome (with 2 pages)
  1247. X;*    8    Hercules graphics mode.
  1248. X;*
  1249. X;**********************************************************
  1250. X;
  1251. XINCLUDE    hercbios.h
  1252. X
  1253. Xextrn    writechar:near,tty:near,scroll_up:near,scroll_down:near
  1254. Xextrn    scr_start:word,scr_length:word,num_rows:byte
  1255. Xextrn    wr_pixel:near
  1256. Xextrn    end_herc:near
  1257. Xpublic    exit_herc_bios,int10,vid_vector
  1258. Xpublic    set_mode,set_curs,read_curs,new_page,status
  1259. X;-----------------------------------------
  1260. Xpage
  1261. X;************************************************************
  1262. X;*
  1263. X;*    Install the Hercules video handler
  1264. X;*
  1265. X;************************************************************
  1266. Xcseg    segment    public
  1267. X    assume    cs:cseg,ds:cseg
  1268. X
  1269. X    ORG    100h
  1270. X;
  1271. XSTART:
  1272. X;
  1273. X    push    ax
  1274. X    push    es
  1275. X    push    ds
  1276. X;
  1277. X    xor    ax,ax        ; zero the acc
  1278. X    mov    es,ax        ; ES points to zero (interrupt vector)
  1279. X    ; Get ROM BIOS video entry point, and save in "rom_bios"
  1280. X    mov    ax,es:[4*VIDI]
  1281. X    mov    word ptr cs:rom_bios,ax
  1282. X    mov    ax,es:[4*VIDI+2]
  1283. X    mov    word ptr cs:rom_bios+2,ax
  1284. X    ; Now plant the HERCBIOS entry point in interrupt vector
  1285. X    mov    ax,offset int10    ; address of video handler to AX
  1286. X    mov    es:[4*VIDI],ax    ; and store it in interrupt vector 10H
  1287. X    mov    ax,cs        ; same for the segment of video handler
  1288. X    mov    es:[4*VIDI+2],ax    ; ...
  1289. X;
  1290. X;   Leave the message that we're installed
  1291. X    mov    ax,cs        ; DS:DX pointing to message
  1292. X    mov    ds,ax
  1293. X    mov    dx,offset install_msg
  1294. X    mov    ah,9        ; display-string function
  1295. X    int    21h
  1296. X
  1297. X    pop    ds
  1298. X    pop    es
  1299. X    pop    ax
  1300. X;
  1301. X    mov    dx,offset end_herc    ; set dx to end of this program
  1302. X    int    27H        ; terminate, but stay resident
  1303. X;
  1304. Xinstall_msg    db    "BIOS for Hercules-compatible Graphics - "
  1305. X    db        "(DMT Aug 1986)",10,13,'$'
  1306. Xpage
  1307. X;************************************************************
  1308. X;*
  1309. X;*    Beginning of video interrupt handler
  1310. X;*
  1311. X;************************************************************
  1312. X;
  1313. X;
  1314. Xint10    proc    far
  1315. X;
  1316. X    sti            ; allow further interrupts
  1317. X    push    ds        ; save DS
  1318. X    push    ax        ; save AX
  1319. X    mov    ax,bios_data    ; bios data segment --> AX
  1320. X    mov    ds,ax        ; now put bios data segment in DS
  1321. X    assume    ds:bios_data    ; and tell assembler about it
  1322. X;            ; check current mode
  1323. X    mov    ah,video_mode    ; get current mode
  1324. X    cmp    ah,herc_mode    ; test for a graphics mode
  1325. X    je    herc_bios
  1326. X    cmp    ah,ibm_mode
  1327. X    je    herc_bios
  1328. X;            ; setmode to a graphics mode?
  1329. X    pop    ax        ; restore AX
  1330. X    push    ax        ; ...but leave it on stack
  1331. X    cmp    ax,0006        ; Fn = set to IBM hi-res mode?
  1332. X    je    herc_bios
  1333. X    cmp    ax,0008        ; Fn = set to Herc graphics mode?
  1334. X    je    herc_bios
  1335. X;
  1336. Xnorm_bios:        ; if we get here, just go to real BIOS
  1337. X    pop    ax        ; restore stack to pre-interrupt state
  1338. X    pop    ds
  1339. X    db    0EAh    ; opcode for FAR JUMP to rom_bios
  1340. Xrom_bios    dd    ?    ; normal video bios address (in ROM)
  1341. X;
  1342. Xherc_bios:        ; jump table for special Hercules BIOS
  1343. X;
  1344. X    pop    ax    ; restore ax
  1345. X    push    bx    ; save regs
  1346. X    push    cx
  1347. X    push    dx
  1348. X    push    si
  1349. X    push    di
  1350. X    push    es
  1351. X;
  1352. X    push    ax
  1353. X    mov    al,ah        ; function # to AX
  1354. X    xor    ah,ah
  1355. X    shl    ax,1        ; *2 for word vector
  1356. X    mov    si,ax        ; put in SI to index into vector
  1357. X    pop    ax        ; restore old AX
  1358. X    cmp    si,offset vid_vec_end-offset vid_vector
  1359. X                ; function number within range?
  1360. X    jge    exit_herc_bios    ; function number out of range
  1361. X    add    si,offset vid_vector
  1362. X    jmp    word ptr cs:[si]
  1363. X                ; jump to routine via vector
  1364. X;
  1365. X
  1366. Xvid_vector:        ; jump vector for hercules video routines
  1367. X    dw    offset set_mode            ; 0 = set mode
  1368. X    dw    offset exit_herc_bios        ; 1 = cursor type (NA)
  1369. X    dw    offset set_curs            ; 2 = set cursor position
  1370. X    dw    offset read_curs        ; 3 = read cursor position
  1371. X    dw    offset exit_herc_bios        ; 4 = light pen (NA)
  1372. X    dw    offset new_page            ; 5 = choose active page
  1373. X    dw    offset scroll_up        ; 6 = scroll up
  1374. X    dw    offset scroll_down        ; 7 = scroll down
  1375. X    dw    offset exit_herc_bios        ; 8 = read character (NA)
  1376. X    dw    offset writechar        ; 9 = write char & attribute
  1377. X    dw    offset writechar        ;10 = write character
  1378. X    dw    offset exit_herc_bios        ;11 = set color palette (NA)
  1379. X    dw    offset wr_pixel            ;12 = write pixel
  1380. X    dw    offset wr_pixel            ;13 = read pixel
  1381. X    dw    offset tty            ;14 = teletype write
  1382. X    dw    offset status            ;15 = return video state
  1383. Xvid_vec_end:
  1384. X;
  1385. Xexit_herc_bios:
  1386. X    pop    es    ; restore regs
  1387. X    pop    di
  1388. X    pop    si
  1389. X    pop    dx
  1390. X    pop    cx
  1391. X    pop    bx
  1392. X    pop    ds
  1393. X    iret        ; and return
  1394. Xpage
  1395. X;********************************************************************
  1396. X;*
  1397. X;*    FUNCTION 0 - SET VIDEO MODE
  1398. X;*
  1399. X;*    Only gets here to set a hi-res graphics mode
  1400. X;*        6=IBM
  1401. X;*        8=Hercules
  1402. X;*    [ AX destroyed ]
  1403. X;*
  1404. X;*******************************************************************
  1405. X;
  1406. Xset_mode:
  1407. X;            ; is it a graphics mode?
  1408. X    cmp    al,herc_mode    ; set to hercules mode?
  1409. X    je    g_mode
  1410. X    cmp    al,ibm_mode    ; set to IBM mode?
  1411. X    je    g_mode
  1412. X                ; Neither. Leave it to normal BIOS
  1413. X    pop    es        ; restore regs
  1414. X    pop    di
  1415. X    pop    si
  1416. X    pop    dx
  1417. X    pop    cx
  1418. X    pop    bx
  1419. X    pop    ds
  1420. X    jmp    vid_bios    ; and go to MPX-16 BIOS
  1421. X;
  1422. Xg_mode:    mov    video_mode,al    ; save video mode in BIOS data area
  1423. X    mov    active_page,ah    ; zero the active page in BIOS data
  1424. X    mov    n_cols,90    ; 90 character columns in graphics mode
  1425. X;
  1426. X;*  clear display area
  1427. X    mov    ax,pixbase    ; get starting address
  1428. X    mov    es,ax        ; page base to ES
  1429. X    mov    cx,8000H    ; word counter
  1430. X    mov    di,0        ; start at beginning of display
  1431. X    cld            ; direction "up"
  1432. X    xor    ax,ax        ; zero AX
  1433. X    rep    stosw        ; write zero to both pages
  1434. X;
  1435. X;*  load the 6845 internal registers
  1436. X;
  1437. X;            ; first set up the loop
  1438. X    push    ds        ; save DS
  1439. X    mov    ax,cs        ; get cseg into DS
  1440. X    mov    ds,ax
  1441. X    assume    ds:cseg
  1442. X    mov    dx,vid_port    ; 6845 index port address to DX
  1443. X    mov    si,offset vid_parm_table
  1444. X                ; table pointer to SI
  1445. X    mov    cx,16        ; 16 parameters in table
  1446. X    xor    ax,ax        ; zero AX (AH will be index counter)
  1447. X;            ; now execute the loop
  1448. Xinit_6845_loop:
  1449. X    mov    al,ah        ; index counter to AL
  1450. X    out    dx,al        ; output index to 6845
  1451. X    inc    dx        ; point DX to data reg
  1452. X    mov    al,[si]        ; get table entry
  1453. X    out    dx,al        ; output to 6845 data reg
  1454. X    dec    dx        ; point DX back to index reg
  1455. X    inc    ah        ; bump index counter
  1456. X    inc    si        ; bump table pointer
  1457. X    loop    init_6845_loop
  1458. X    pop    ds        ; restore DS
  1459. X    assume    ds:bios_data    ; restore DS assumed
  1460. X;
  1461. X;*  now set the 6845 control register
  1462. X    mov    dx,vid_port+4    ; control port address
  1463. X    mov    al,0AH        ; graphics control byte
  1464. X    cmp    active_page,0    ; get current page
  1465. X    je    pg0_F0        ; skip if zero
  1466. X    or    al,80H        ; page 1 to control byte
  1467. Xpg0_F0:    out    dx,al        ; and ship to 6845
  1468. X    mov    chip_ctrl,al    ; also save in bios data area
  1469. X;
  1470. X;*  save cursor position (0,0) in bios data area
  1471. X    xor    ax,ax        ; zero AX
  1472. X    mov    curs_pos,ax    ; write zero to pg.0 cursor postion
  1473. X    mov    curs_pos+2,ax    ; write zero to pg.1 cursor postion
  1474. X;
  1475. X;*  initialize scrolling parameters
  1476. X;
  1477. X    cmp    video_mode,herc_mode
  1478. X    je    h_parm
  1479. X    mov    cs:scr_start,180    ; IBM parameters
  1480. X    mov    cs:scr_length,3690    ;
  1481. X    mov    cs:num_rows,42        ;
  1482. X    jmp    parm_done
  1483. Xh_parm:    mov    cs:scr_start,270    ; Herc parameters
  1484. X    mov    cs:scr_length,3645    ;
  1485. X    mov    cs:num_rows,28        ;
  1486. Xparm_done:
  1487. X;
  1488. X    jmp    exit_herc_bios
  1489. X;
  1490. X;*  table of 6845 chip parameters
  1491. X;
  1492. Xvid_parm_table    db    53,45,46,7,91,2,87,87,2,3,62H,3,0,0,0,0
  1493. X;vid_parm_table    db    54,45,46,8,91,2,87,87,2,3,62H,3,0,0,0,0
  1494. X                        ;DMT's monitor
  1495. Xpage
  1496. X;********************************************************************
  1497. X;*
  1498. X;*    FUNCTION 2 - SET CURSOR POSITION
  1499. X;*
  1500. X;*    DX = new row (DH) and column (DL)
  1501. X;*    BH = display page number
  1502. X;*
  1503. X;********************************************************************
  1504. X;
  1505. Xset_curs:
  1506. X;
  1507. X; *   save in BIOS data area
  1508. X    mov    bl,bh        ; page # to bl
  1509. X    xor    bh,bh        ; zero bh (page # = BX)
  1510. X    shl    bx,1        ; times 2 for word
  1511. X    mov    curs_pos[bx],dx    ; store in data area
  1512. X;
  1513. X; *   if page # = active page, then we should actually move cursor
  1514. X; *          However, cursor doesn't show in graphics mode, so we won't.
  1515. X;
  1516. X    jmp    exit_herc_bios
  1517. X;
  1518. Xpage
  1519. X;********************************************************************
  1520. X;*
  1521. X;*    FUNCTION 3 - READ CURSOR POSITION
  1522. X;*
  1523. X;*    on entry
  1524. X;*        BH = display page number
  1525. X;*
  1526. X;*    on exit
  1527. X;*        CX = cursor type/size
  1528. X;*        DX = current row (DH) and column (DL)
  1529. X;*
  1530. X;********************************************************************
  1531. X;
  1532. Xread_curs:
  1533. X;            ; uncover the return portion of the stack
  1534. X    pop    es
  1535. X    pop    di
  1536. X    pop    si
  1537. X    pop    dx
  1538. X    pop    cx
  1539. X;            ; now get the data and push onto stack
  1540. X    push    curs_mode    ; cursor type to CX position in stack
  1541. X    mov    bl,bh        ; page # to BX
  1542. X    xor    bh,bh
  1543. X    shl    bx,1        ; *2 for word offset
  1544. X    push    curs_pos[bx]    ; cursor position for specified page
  1545. X                ;   to DX position in stack
  1546. X;            ; refill the stack for return
  1547. X    push    si
  1548. X    push    di
  1549. X    push    es
  1550. X;
  1551. X    jmp    exit_herc_bios
  1552. Xpage
  1553. X;********************************************************************
  1554. X;*
  1555. X;*    FUNCTION 5 - SELECT NEW DISPLAY PAGE
  1556. X;*
  1557. X;*    AL = new display page number
  1558. X;*
  1559. X;********************************************************************
  1560. X;
  1561. Xnew_page:
  1562. X    cmp    al,2        ; page < 2?
  1563. X    jl    f5_1        ; yup
  1564. X    jmp    exit_herc_bios    ; nope. can't do it.
  1565. X;
  1566. Xf5_1:    mov    active_page,al    ; put away active page in bios data
  1567. X;  * put starting address in 6845 register 12
  1568. X    mov    ah,al        ; save page number in AH
  1569. X    mov    dx,vid_port    ; index pointer address
  1570. X    mov    al,12        ; save in register 12
  1571. X    out    dx,al        ; and set index pointer to 12
  1572. X    mov    al,ah        ; restore page to AL
  1573. X    ror    al,1        ; page to high-order bit
  1574. X    shr    al,1        ; two bytes per word
  1575. X    inc    dx
  1576. X    out    dx,al        ; ...and output it to register
  1577. X;  * put control byte in 6845 port
  1578. X    mov    al,ah        ; get back page number
  1579. X    ror    al,1        ; page to high-order bit
  1580. X    or    al,0AH        ; create chip control byte
  1581. X    mov    chip_ctrl,al    ; save it in data area
  1582. X    mov    dx,vid_port+4    ; control port address
  1583. X    out    dx,al        ; send control byte to chip
  1584. X;
  1585. X    jmp    exit_herc_bios
  1586. Xpage
  1587. X;***********************************************************************
  1588. X;*
  1589. X;*    FUNCTION 15 - RETURN VIDEO STATUS
  1590. X;*
  1591. X;*    On exit:
  1592. X;*        AL = current video mode
  1593. X;*        AH = number of active display columns
  1594. X;*        BH = current active page number
  1595. X;*
  1596. X;***********************************************************************
  1597. X;
  1598. Xstatus:
  1599. X;            ; first uncover the stack
  1600. X    pop    es
  1601. X    pop    di
  1602. X    pop    si
  1603. X    pop    dx
  1604. X    pop    cx
  1605. X    pop    bx
  1606. X;            ; now get the parameters needed
  1607. X    mov    al,video_mode
  1608. X    mov    ah,90        ; all our graphics modes have 90 cols
  1609. X    mov    bh,active_page
  1610. X;            ; and push back onto the stack for return
  1611. X    push    bx
  1612. X    push    cx
  1613. X    push    dx
  1614. X    push    si
  1615. X    push    di
  1616. X    push    es
  1617. X;
  1618. X    jmp    exit_herc_bios
  1619. X;
  1620. Xint10    endp
  1621. X;
  1622. Xcseg    ends
  1623. X    end    START
  1624. SHAR_EOF
  1625. echo x - extracting shar
  1626. sed 's/^X//' << 'SHAR_EOF' > hercbios.aut
  1627. X
  1628. X================================================================================
  1629. X
  1630. XNewsgroups: net.sources
  1631. XPath: decwrl!pyramid!hplabs!hao!nbires!seismo!caip!clyde!cbatt!cbosgd!ihnp4!drutx!mtuxo!mtuxt!dmt
  1632. XSubject: Hercules graphics BIOS
  1633. XPosted: 28 Aug 86 02:47:07 GMT
  1634. XOrganization: AT&T Information Systems, Holmdel NJ
  1635. XWell, here's the promised Hercules driverfor the PC.  It's in SHAR format,
  1636. Xand the instructions for assembly and use are in "hercbios.doc".
  1637. XEnjoy!
  1638. X---------------------------------------------------------------
  1639. X       ---===        Dave Tutelman
  1640. X    -------=====    Physical - AT&T Information Systems
  1641. X  ----------======        Room 1H120
  1642. X ==--------========        Juniper Plaza, Route 9
  1643. X  ====---=========        Freehold, NJ 07728
  1644. X    ============    Logical  - ...ihnp4!mtuxo!mtuxt!dmt
  1645. X       ======        Audible  - (201)-577-4232
  1646. X---------------------------------------------------------------SHAR_EOF
  1647. echo x - extracting shar
  1648. sed 's/^X//' << 'SHAR_EOF' > hercbios.h
  1649. X.XLIST
  1650. X    page    66,132
  1651. X;************************************************************
  1652. X;
  1653. X;    Header file for inclusion in HERCBIOS assemblies
  1654. X;
  1655. X;        Dave Tutelman - 8/86
  1656. X;
  1657. X;*************************************************************
  1658. X
  1659. X;iAPX286    equ    1    ; UN-COMMENT FOR A 186 or 286 MACHINE!
  1660. X                ;   Some of the "ugly" constructs are for speed
  1661. X                ;   on the 808X, while the "obvious" constructs
  1662. X                ;   run faster on the 186 & 286.
  1663. XVIDI        equ    10H    ; video interrupt, 10H for real, 50H for debug
  1664. Xpixbase        equ    0B000H    ; beginning segment of graphics board
  1665. Xmpx_bios    equ    0F000H    ; MPX-16 BIOS segment address
  1666. Xvid_offset    equ    0F065H    ; MPX-16 video offset in BIOS
  1667. Xcharbase    equ    0FA6EH    ; MPX-16 BIOS character table offset
  1668. Xherc_mode    equ    8    ; Hercules graphics mode
  1669. Xibm_mode    equ    6    ; IBM Hi-Res color graphics mode.
  1670. X                ; we'll try to handle it.
  1671. Xvid_port    equ    03B4H    ; 6845 index register (data reg = 3B5H )
  1672. X                ;              (control port = 3B8H )
  1673. X;------------------------------------------
  1674. Xbios    segment at    mpx_bios    ; setup call to vid_bios
  1675. X        org    vid_offset
  1676. Xvid_bios    proc    far
  1677. Xvid_bios    endp
  1678. Xbios        ends
  1679. X;------------------------------------------------
  1680. Xbios_data    segment at 040h
  1681. X        org    049h
  1682. Xvideo_mode    db    ?    ; current video mode
  1683. Xn_cols        dw    ?    ; number of columns in video display
  1684. X        org    050h
  1685. Xcurs_pos    dw    8 dup(?) ; cursor for each of 8 pages
  1686. Xcurs_mode    dw    ?    ; cursor mode
  1687. Xactive_page    db    ?    ; current active display page
  1688. Xvideo_base    dw    ?    ; video port base
  1689. Xchip_ctrl    db    ?    ; current setting of 3X8 register
  1690. Xbios_data ends
  1691. X;------------------------------------
  1692. Xintvec         segment at 0        ; interrupt vector
  1693. X        org    4*1Fh        ; interrupt 1FH
  1694. Xuser_table    dd    ?
  1695. Xintvec         ends
  1696. X;------------------------------------
  1697. X
  1698. XIFDEF    iAPX286
  1699. X    .286c            ; allow 286/186-only instructions
  1700. XENDIF
  1701. X
  1702. X.LIST
  1703. SHAR_EOF
  1704. echo x - extracting shar
  1705. sed 's/^X//' << 'SHAR_EOF' > hercdemo.asm
  1706. X        page    ,132
  1707. X    title    hercdemo - quick and dirty herc demo
  1708. X;
  1709. X; Hercdemo - (c) 1986 by Reid Brown, P.O. Box 1023, Issaquah, WA.  98027
  1710. X;
  1711. X;    This is a quick and dirty program to show off the Hercules
  1712. X;    board.  I place if freely into the public domain so others
  1713. X;    can diddle their Herc boards as well, so long as it is not
  1714. X;    used for any commercial purposes.
  1715. X;
  1716. X
  1717. Xmessage    macro    row,col,string
  1718. X    mov    cx,row
  1719. X    mov    bx,col
  1720. X    mov    si,offset string
  1721. X    call    print
  1722. X        endm
  1723. X
  1724. Xhdraw    macro    row,col,len
  1725. X    mov    cx,row
  1726. X    mov    bx,col
  1727. X    mov    dx,len
  1728. X    call    hline
  1729. X        endm
  1730. X
  1731. Xvdraw    macro    row,col,len
  1732. X    mov    cx,row
  1733. X    mov    bx,col
  1734. X    mov    dx,len
  1735. X    call    vline
  1736. X        endm
  1737. X
  1738. Xcode    segment
  1739. X    assume    cs:code, ds:code, es:code, ss:code
  1740. X        org     100h
  1741. Xstart:    jmp    begin
  1742. X
  1743. XIBMROM    equ    0F000h
  1744. XCHARTAB    equ    0FA6Eh
  1745. XHERCSEG    equ    0B800h
  1746. X
  1747. XMODEPORT equ    3B8h
  1748. X
  1749. XSTRING0 db      'HERCULES DEMO',0
  1750. XSTRING1    db    'A funny thing happened on the way to the forum.',0
  1751. XSTRING2    db    'You, too, can have a rewarding career in computers...',0
  1752. XSTRING3 db      'Strike any key to proceed...',0
  1753. X
  1754. X
  1755. XCON8    db    8
  1756. XCON180    db    180
  1757. X
  1758. Xbegin    proc    near
  1759. X    mov    dx, MODEPORT        ; select herc mode port
  1760. X    mov    al, 08Ah
  1761. X    out    dx, al            ; graphics mode, video on, page 1
  1762. X
  1763. X    call    graphics        ; set 6845 for graphics
  1764. X        call    clear            ; clear screen RAM
  1765. X
  1766. X        vdraw   10,5,20                 ; draw a vertical
  1767. X        vdraw   10,65,20                ; - hopefully, a box!
  1768. X        hdraw   10,6,60                 ; draw a line
  1769. X        hdraw   30,6,60                 ; and another
  1770. X
  1771. X        message 12,29,STRING0           ; 1st message
  1772. X        message 17,10,STRING1           ; 2nd message
  1773. X        message 23,10,STRING2           ; 3nd message
  1774. X        message 29,20,STRING3           ; ...
  1775. X        
  1776. X;
  1777. X; done - clean up and reset
  1778. X;
  1779. X        mov    ax, 0C07h        ; flush buffer, read char
  1780. X    int    21h            ; wait for any input
  1781. X
  1782. X        call    text                    ; reset 6845
  1783. X
  1784. X    mov    dx, MODEPORT        ; select herc mode port
  1785. X    mov    al, 00001000B        ; re-enable mono
  1786. X    out    dx, al
  1787. X        
  1788. X    mov    ax, 4C00h
  1789. X    int    21h            ; exit
  1790. Xbegin    endp
  1791. X
  1792. X;
  1793. X; print - print text in graphics mode
  1794. X;
  1795. X;    cx = row
  1796. X;    bx = column
  1797. X;    si = address of string (null terminated) to print
  1798. X;
  1799. Xprint    proc    near
  1800. X
  1801. Xloop:    lodsb                ; get next char
  1802. X    or    al, al            ; end of display?
  1803. X    je    pdone
  1804. X    call    display
  1805. X    inc    bx            ; bump to next column
  1806. X    jmp    loop
  1807. Xpdone:    ret
  1808. X
  1809. Xprint    endp
  1810. X
  1811. X;
  1812. X; display - output an 8x8 character from the IBM ROM to the Herc board
  1813. X;
  1814. X; AX = char, BX = column (0-89), CX = row(0-42)  ** all preserved **
  1815. X;
  1816. Xdisplay    proc near
  1817. X    push    ds            ; save the lot
  1818. X    push    es
  1819. X    push    ax
  1820. X    push    bx
  1821. X    push    cx
  1822. X    push    dx
  1823. X    push    si
  1824. X    push    di
  1825. X
  1826. X; setup ds -> IBM ROM, and si -> index into IBM ROM character table located
  1827. X;    at 0fa6eh in the ROM
  1828. X
  1829. X    and    ax, 07fh
  1830. X    mul    CS:CON8            ; mult by 8 bytes of table per char
  1831. X    mov    si, ax
  1832. X    mov    ax, IBMROM
  1833. X    mov    ds, ax
  1834. X    assume    ds:nothing
  1835. X    add    si, CHARTAB        ; add offset of character table
  1836. X
  1837. X; compute index into Hercules screen memory for scan line 0.  The remaining
  1838. X;    seven scan lines are all at fixed offsets from the first.
  1839. X;
  1840. X;    Since graphics mode treats the screen as sets of 16x4 "characters",
  1841. X;    we need to map an 8x8 real character onto the front or back of
  1842. X;    a pair of graphics "characters".  The first four scan lines of our
  1843. X;    8x8 character will map to the top graphics "character", and the second
  1844. X;    four scan lines map to the graphics character on the "line" (4 scan
  1845. X;    lines high) below it.
  1846. X;
  1847. X;    For some exotic hardware reason (probably speed), all scan line 0
  1848. X;    bits (i.e. every fourth scan line) are stored in memory locations
  1849. X;    0-2000h in the screen buffer.  All scan line 1 bits are stored
  1850. X;    2000h-4000h.  Within these banks, they are stored by rows.  The first
  1851. X;    scan line on the screen (scan line 0 of graphics character row 0)
  1852. X;    is the first 45 words of memory in the screen buffer.  The next 45
  1853. X;    words are the first scan line graphics row 1, and since graphics
  1854. X;    "characters" are 4 bits high, this second scan line is physically
  1855. X;    the fifth scan line displayed on the screen.
  1856. X;
  1857. X;    SO, to display an 8x8 character, the 1st and 5th rows of dots are
  1858. X;    both scan line 0 of the graphics "character", the 2nd and 6th are
  1859. X;    scan line 1, and so on.
  1860. X;
  1861. X;    The column (0-89) tells which byte in a scan line we need to load.
  1862. X;    Since it takes two rows of graphics characters to hold one row of
  1863. X;    our characters, column+90 is a index to scan line 4 rows of pixels
  1864. X;    higher (n+4).  Thus 180 bytes of screen memory in any bank (0h, 2000h,
  1865. X;    4000h, 6000h) represent a row of 8x8 characters.
  1866. X;    
  1867. X;    The starting location in screen memory for the first scan line of
  1868. X;    a character to be displayed will be:      (row*180)+column
  1869. X;    The 5th scan line will be at:        (row*180)+column+90
  1870. X;
  1871. X;    The second and 6th scan lines will be at the above offsets plus
  1872. X;    the bank offset of 2000h.  The third and 7th, add 4000h and finally
  1873. X;    the 4th and 8th, add 6000h.
  1874. X;
  1875. X    mov    ax, HERCSEG
  1876. X    mov    es, ax            ; es = hercules page 0
  1877. X    mov    ax, cx            ; get row
  1878. X    mul    CS:CON180        ; mult by 180(10)
  1879. X    mov    di, ax            ; di = index reg
  1880. X    cld                ; insure right direction
  1881. X
  1882. X;output 8 segments of character to video ram
  1883. X
  1884. X    lodsb                ; line 0
  1885. X    mov    es:[di+bx], al
  1886. X    lodsb
  1887. X    mov    es:[di+bx+2000h], al    ; line 1
  1888. X    lodsb
  1889. X    mov    es:[di+bx+4000h], al    ; line 2
  1890. X    lodsb
  1891. X    mov    es:[di+bx+6000h], al    ; line 3
  1892. X    lodsb
  1893. X    mov    es:[di+bx+90], al    ; line 4
  1894. X    lodsb
  1895. X    mov    es:[di+bx+2000h+90], al    ; line 5
  1896. X    lodsb
  1897. X    mov    es:[di+bx+4000h+90], al    ; line 6
  1898. X    lodsb
  1899. X    mov    es:[di+bx+6000h+90], al    ; line 7
  1900. X
  1901. X    pop    di
  1902. X    pop    si
  1903. X    pop    dx
  1904. X    pop    cx
  1905. X    pop    bx
  1906. X    pop    ax
  1907. X    pop    es
  1908. X    pop    ds
  1909. X    ret
  1910. Xdisplay    endp
  1911. X
  1912. X;
  1913. X; clear - clear page 1 of the screen buffer to zero (effectively, blank
  1914. X;    the screen)
  1915. X;
  1916. Xclear   proc
  1917. X        push    es
  1918. X        push    ax
  1919. X        push    cx
  1920. X        push    di
  1921. X
  1922. X    mov    ax, HERCSEG
  1923. X    mov    es, ax
  1924. X    xor    di, di
  1925. X    mov    cx, 4000h
  1926. X    xor    ax, ax
  1927. X    cld
  1928. X
  1929. X    rep stosw            ; zero out screen page
  1930. X    
  1931. X    pop    di
  1932. X    pop    cx
  1933. X    pop    ax
  1934. X    pop    es
  1935. X    ret
  1936. Xclear    endp
  1937. X
  1938. X;
  1939. X; hline - draw a horizontal line at scan line 0 of a specified 8x8 character
  1940. X;    cell sized row, for a specified no. of characters
  1941. X;
  1942. X;    cx = row
  1943. X;    bx = col
  1944. X;    dx = len
  1945. X;
  1946. Xhline    proc near
  1947. X        push    es
  1948. X        push    ax
  1949. X        push    cx
  1950. X        push    di
  1951. X
  1952. X    mov    ax,cx            ; copy to accum for multiply
  1953. X    mul    cs:CON180        ; mult by 180 to get offset
  1954. X    mov    di,ax            ; copy to dest ptr
  1955. X    add    di,bx            ; add column offset
  1956. X    mov    cx,dx            ; put byte count in count reg
  1957. X    mov    ax, HERCSEG
  1958. X    mov    es, ax
  1959. X        mov     ax, 0ffh        ; pattern = all bits ON
  1960. X    cld
  1961. X
  1962. X    rep stosb            ; put bits on screen
  1963. X    
  1964. X    pop    di
  1965. X    pop    cx
  1966. X    pop    ax
  1967. X    pop    es
  1968. X    ret
  1969. X
  1970. Xhline    endp
  1971. X
  1972. X;
  1973. X; vline - draw a vertical line in the last bit position of a given char
  1974. X;    cell, extending downward for a specified no. of chars
  1975. X;
  1976. X;    cx = row
  1977. X;    bx = col
  1978. X;    dx = len
  1979. X;
  1980. Xvline    proc near
  1981. X        push    es
  1982. X        push    ax
  1983. X        push    cx
  1984. X        push    di
  1985. X
  1986. X    mov    ax,cx            ; copy to accum for multiply
  1987. X    mul    cs:CON180        ; mult by 180 to get offset
  1988. X    mov    di,ax            ; copy to dest ptr
  1989. X    mov    cx,dx            ; put byte count in count reg
  1990. X    mov    ax, HERCSEG
  1991. X    mov    es, ax
  1992. X        mov     ax, 1            ; pattern = last bit on
  1993. X
  1994. Xvloop:    mov    es:[di+bx], al
  1995. X    mov    es:[di+bx+2000h], al    ; line 1
  1996. X    mov    es:[di+bx+4000h], al    ; line 2
  1997. X    mov    es:[di+bx+6000h], al    ; line 3
  1998. X    mov    es:[di+bx+90], al    ; line 4
  1999. X    mov    es:[di+bx+2000h+90], al    ; line 5
  2000. X    mov    es:[di+bx+4000h+90], al    ; line 6
  2001. X    mov    es:[di+bx+6000h+90], al    ; line 7
  2002. X    add    di,180                ; advance to next line
  2003. X    loop    vloop            ; continue for all rows
  2004. X    
  2005. X    pop    di
  2006. X    pop    cx
  2007. X    pop    ax
  2008. X    pop    es
  2009. X    ret
  2010. X
  2011. Xvline    endp
  2012. X
  2013. Xgraphics proc near
  2014. X    mov    si, offset graph_parms
  2015. Xg_cont:    mov    dx, 3b4h        ; point to index reg
  2016. X    mov    cx, 16
  2017. X    xor    ax, ax
  2018. Xg_loop:    mov    al, ah
  2019. X    out    dx, al
  2020. X    inc    dx
  2021. X    mov    al, [si]
  2022. X    out    dx, al
  2023. X    dec    dx
  2024. X    inc    ah
  2025. X    inc    si
  2026. X    loop    g_loop
  2027. X    ret
  2028. Xgraph_parms db    35h,2dh,2eh,7,5bh,2,57h,57h,2,3,0,0,0,0,0,0
  2029. Xgraphics endp
  2030. X
  2031. Xtext    proc    near
  2032. X    mov    si, offset text_parms
  2033. X    jmp    g_cont
  2034. Xtext_parms db    61h,50h,52h,0fh,19h,6,19h,19h,2,0dh,0bh,0ch,00,00,00,00
  2035. Xtext    endp
  2036. X
  2037. X
  2038. Xcode    ends
  2039. X
  2040. X    end    start
  2041. SHAR_EOF
  2042. echo x - extracting shar
  2043. sed 's/^X//' << 'SHAR_EOF' > hercmake.att
  2044. X
  2045. X# Makefile for HERCBIOS.COM
  2046. XSRC=hercbios gchar graph
  2047. XDEST=a:
  2048. X
  2049. Xhercbios.com : hercbios.obj gchar.obj graph.obj
  2050. X    link hercbios gchar graph,,/MAP;
  2051. X    exe2bin  hercbios.exe  hercbios.com
  2052. X    del hercbios.exe
  2053. X
  2054. Xhercbios.obj : hercbios.asm hercbios.h
  2055. Xgchar.obj : gchar.asm hercbios.h
  2056. Xgraph.obj : graph.asm hercbios.h
  2057. X
  2058. X
  2059. X# Makes for the demo & test program, using deSmet C
  2060. X
  2061. Xtestpix.exe : testpix.o hercpixl.o
  2062. X    bind testpix hercpixl
  2063. X
  2064. Xtestpix.o : testpix.c
  2065. X    c88 testpix
  2066. X
  2067. Xhercpixl.o : hercpixl.c
  2068. X    c88 hercpixl
  2069. X
  2070. X# Make a backup or distribution disk
  2071. Xbackup :
  2072. X    for %f in ($(SRC)) do  copy %f.asm $(DEST)
  2073. X    copy hercbios.h   $(DEST)
  2074. X    copy hercbios.com $(DEST)
  2075. X    copy hercbios.doc $(DEST)
  2076. X    copy makefile $(DEST)
  2077. X
  2078. Xdistrib :
  2079. X    make backup
  2080. X    copy hercpixl.c $(DEST)
  2081. X    copy testpix.* $(DEST)
  2082. X    copy hcharset.* $(DEST)SHAR_EOF
  2083. echo x - extracting shar
  2084. sed 's/^X//' << 'SHAR_EOF' > hercmake.lcm
  2085. X#
  2086. X# Makefile for HERCBIOS.COM
  2087. X#       (designed for Larry Campbell's version of MAKE)
  2088. X#
  2089. X
  2090. Xhercbios.com : hercbios.obj gchar.obj graph.obj
  2091. X    link hercbios gchar graph,,/MAP;
  2092. X    exe2bin  hercbios.exe  hercbios.com
  2093. X    del hercbios.exe
  2094. X
  2095. Xhercbios.obj : hercbios.asm hercbios.h
  2096. X        masm hercbios,,;
  2097. X
  2098. Xgchar.obj : gchar.asm hercbios.h
  2099. X        masm gchar,,;
  2100. X
  2101. Xgraph.obj : graph.asm hercbios.h
  2102. X        masm graph,,;
  2103. X
  2104. X
  2105. X#
  2106. X# Makes for the demo & test program, using Lattice
  2107. X#       (Note: you may have to change the drive and path specs)
  2108. X#
  2109. X
  2110. Xtestpix.exe : testpix.obj hercpixl.obj
  2111. X    link g:\lc\s\c testpix hercpixl,testpix,testpix/m,g:\lc\s\lc
  2112. X
  2113. Xtestpix.obj : testpix.c
  2114. X    lc -ms -n -ig:\lc\ testpix
  2115. X
  2116. Xhercpixl.obj : hercpixl.c
  2117. X    lc -ms -n -ig:\lc\ hercpixl
  2118. SHAR_EOF
  2119. echo x - extracting shar
  2120. sed 's/^X//' << 'SHAR_EOF' > hercpixl.dc
  2121. X/*
  2122. X *    HERCPIXL.C
  2123. X *    Dave Tutelman  -  last modified 8/86
  2124. X *
  2125. X *    This is a set of basic graphic routines for the Hercules
  2126. X *    Board (or at least the SuperComputer version of it; I assume
  2127. X *     that they work with the real thing).
  2128. X *        alfa ()        puts us in alphanumeric mode.
  2129. X *        grafix (page)    puts us in graphics mode in page 0 or 1
  2130. X *        pixel (x,y,val)    puts a pixel at <x,y>. Bright dot if
  2131. X *                val=1, dark dot if val=0.
  2132. X *         dchar (x,y,c)    puts character "c" at <x,y>. Note that
  2133. X *                character raster is 90 x 29.
  2134. X *        swpage (page)    switches to a different page.
  2135. X *            waitkey ()    just waits till a key is pressed.
  2136. X *
  2137. X *    Actually, the routines should work with any board, since the
  2138. X *    BIOS calls are used throughout.  It's Hercules-specific only
  2139. X *    because I've defined the graphics and alpha modes for my
  2140. X *    Hercules BIOS.
  2141. X *
  2142. X *    Compile with deSmet C.
  2143. X */
  2144. X
  2145. X#define VIDI    0x10        /* video interrupt, normally 10H  */
  2146. X#define    KBD    0x16        /* keyboard interrupt */
  2147. X#define ALFA_MODE    7    /* monochrome alpha mode */
  2148. X#define GRAF_MODE    8    /* Hercules graphics mode */
  2149. X
  2150. Xint    page = 0;
  2151. Xextern unsigned _rax,_rbx,_rcx,_rdx;
  2152. X
  2153. X/*
  2154. X * This puts us back in alphanumeric mode 
  2155. X */
  2156. X
  2157. Xalfa (dummy)
  2158. X    unsigned int dummy;
  2159. X{
  2160. X    _rax = ALFA_MODE;    /* mono 80-col mode */
  2161. X    _doint ( VIDI );    /* set mode */
  2162. X}
  2163. X
  2164. X/*
  2165. X *    This one switches us to hercules graphics mode
  2166. X *        in page 0 or 1
  2167. X */
  2168. X
  2169. Xgrafix (newpage)
  2170. X    int newpage;
  2171. X{
  2172. X
  2173. X    _rax = GRAF_MODE;            /* herc grafix mode */
  2174. X    _doint ( VIDI );    /* set mode */
  2175. X
  2176. X    /*  now set the page */
  2177. X    swpage (newpage);
  2178. X}
  2179. X
  2180. X/*
  2181. X *   This writes a pixel at (x,y), where (0,0) is the upper-left
  2182. X *   corner of the screen.  If val = 0 then the pixel is erased.
  2183. X */
  2184. X
  2185. Xpixel (x, y, val)
  2186. X    int x, y, val;
  2187. X{
  2188. X
  2189. X    _rax = 0x0C00 + val;    /* function 12      */    
  2190. X    _rcx = x;
  2191. X    _rdx = y;
  2192. X    _doint ( VIDI );    /* set mode */
  2193. X
  2194. X}
  2195. X
  2196. X
  2197. X/*
  2198. X *    dchar (x,y,c)    puts character "c" at <x,y>. Note that
  2199. X *            character raster is 90 x 25.
  2200. X */
  2201. X
  2202. Xdchar (x,y,c)
  2203. X    int x,y;
  2204. X    char c;
  2205. X{
  2206. X
  2207. X    _rax = 2*256;        /* AH=Fn#2 */
  2208. X    _rdx = 256*y + x;        /* DH=row, DX=col */
  2209. X    _rbx = page * 256;        /* BH=page  */
  2210. X    _doint (VIDI);        /* set cursor */
  2211. X
  2212. X    _rax = 10*256 + (int) c;    /* AH=Fn#10, AL=char */
  2213. X    _rbx = page * 256;        /* BH=page */
  2214. X    _rcx = 1;            /* CX=count */
  2215. X    _doint (VIDI);        /* write character */
  2216. X}
  2217. X
  2218. X
  2219. X/*
  2220. X *    This one switches us to a different page, without changing
  2221. X *    the contents of that page.
  2222. X */
  2223. X
  2224. Xswpage (newpage)
  2225. X    int     newpage;
  2226. X{
  2227. X    page = newpage;
  2228. X    _rax = 0x500 + page;        /* new page function */
  2229. X    _doint ( VIDI );    /* interrupt call */
  2230. X}
  2231. X
  2232. X
  2233. Xwaitkey ()
  2234. X{
  2235. X    _rax = 0;        /* keyboard blocking read function */
  2236. X    _doint (KBD);
  2237. X}
  2238. SHAR_EOF
  2239. echo x - extracting shar
  2240. sed 's/^X//' << 'SHAR_EOF' > hercpixl.lc
  2241. X/*
  2242. X *    HERCPIXL.C
  2243. X *    Dave Tutelman  -  last modified 8/86
  2244. X *
  2245. X *    This is a set of basic graphic routines for the Hercules
  2246. X *    Board (or at least the SuperComputer version of it; I assume
  2247. X *     that they work with the real thing).
  2248. X *        alfa ()        puts us in alphanumeric mode.
  2249. X *        grafix (page)    puts us in graphics mode in page 0 or 1
  2250. X *        pixel (x,y,val)    puts a pixel at <x,y>. Bright dot if
  2251. X *                val=1, dark dot if val=0.
  2252. X *         dchar (x,y,c)    puts character "c" at <x,y>. Note that
  2253. X *                character raster is 90 x 29.
  2254. X *        swpage (page)    switches to a different page.
  2255. X *            waitkey ()    just waits till a key is pressed.
  2256. X *
  2257. X *    Actually, the routines should work with any board, since the
  2258. X *    BIOS calls are used throughout.  It's Hercules-specific only
  2259. X *    because I've defined the graphics and alpha modes for my
  2260. X *    Hercules BIOS.
  2261. X *
  2262. X *      Modified for Lattice C: Reid L. Brown
  2263. X *                              9/4/86
  2264. X */
  2265. X
  2266. X#define VIDI    0x10        /* video interrupt, normally 10H  */
  2267. X#define    KBD    0x16        /* keyboard interrupt */
  2268. X#define ALFA_MODE    7    /* monochrome alpha mode */
  2269. X#define GRAF_MODE    8    /* Hercules graphics mode */
  2270. X
  2271. Xint    page = 0;
  2272. Xstruct {
  2273. X    unsigned ax,bx,cx,dx,si,di;
  2274. X        } _r;
  2275. X
  2276. X/*
  2277. X * This puts us back in alphanumeric mode 
  2278. X */
  2279. X
  2280. Xalfa (dummy)
  2281. X    unsigned int dummy;
  2282. X{
  2283. X    _r.ax = ALFA_MODE;    /* mono 80-col mode */
  2284. X    int86 ( VIDI, &_r, &_r);    /* set mode */
  2285. X}
  2286. X
  2287. X/*
  2288. X *    This one switches us to hercules graphics mode
  2289. X *        in page 0 or 1
  2290. X */
  2291. X
  2292. Xgrafix (newpage)
  2293. X    int newpage;
  2294. X{
  2295. X
  2296. X    _r.ax = GRAF_MODE;    /* herc grafix mode */
  2297. X    int86 ( VIDI, &_r, &_r);    /* set mode */
  2298. X
  2299. X    /*  now set the page */
  2300. X    swpage (newpage);
  2301. X}
  2302. X
  2303. X/*
  2304. X *   This writes a pixel at (x,y), where (0,0) is the upper-left
  2305. X *   corner of the screen.  If val = 0 then the pixel is erased.
  2306. X */
  2307. X
  2308. Xpixel (x, y, val)
  2309. X    int x, y, val;
  2310. X{
  2311. X
  2312. X    _r.ax = 0x0C00 + val;    /* function 12      */    
  2313. X    _r.cx = x;
  2314. X    _r.dx = y;
  2315. X    int86 ( VIDI, &_r, &_r);    /* set mode */
  2316. X
  2317. X}
  2318. X
  2319. X
  2320. X/*
  2321. X *    dchar (x,y,c)    puts character "c" at <x,y>. Note that
  2322. X *            character raster is 90 x 25.
  2323. X */
  2324. X
  2325. Xdchar (x,y,c)
  2326. X    int x,y;
  2327. X    char c;
  2328. X{
  2329. X
  2330. X    _r.ax = 2*256;        /* AH=Fn#2 */
  2331. X    _r.dx = 256*y + x;        /* DH=row, DX=col */
  2332. X    _r.bx = page * 256;        /* BH=page  */
  2333. X    int86 ( VIDI, &_r, &_r);    /* set cursor */
  2334. X
  2335. X    _r.ax = 10*256 + (int) c;    /* AH=Fn#10, AL=char */
  2336. X    _r.bx = page * 256;        /* BH=page */
  2337. X    _r.cx = 1;            /* CX=count */
  2338. X    int86 ( VIDI, &_r, &_r);    /* write character */
  2339. X}
  2340. X
  2341. X
  2342. X/*
  2343. X *    This one switches us to a different page, without changing
  2344. X *    the contents of that page.
  2345. X */
  2346. X
  2347. Xswpage (newpage)
  2348. X    int     newpage;
  2349. X{
  2350. X    page = newpage;
  2351. X    _r.ax = 0x500 + page;        /* new page function */
  2352. X    int86 ( VIDI, &_r, &_r );    /* interrupt call */
  2353. X}
  2354. X
  2355. X
  2356. Xwaitkey ()
  2357. X{
  2358. X    _r.ax = 0;        /* keyboard blocking read function */
  2359. X    int86 (KBD, &_r, &_r );
  2360. X}
  2361. SHAR_EOF
  2362. echo x - extracting shar
  2363. sed 's/^X//' << 'SHAR_EOF' > testpix.c
  2364. X
  2365. X/*  MAIN tests PIXEL by drawing lines on the screen  */
  2366. X
  2367. X#include    "stdio.h"
  2368. X
  2369. Xmain ()
  2370. X{
  2371. X    int i,j;
  2372. X    char    line [90];
  2373. X
  2374. X    /* first clear screen */
  2375. X    grafix (0);
  2376. X
  2377. X    /* now draw a couple of lines */
  2378. X    for (i=0; i<696; i++)
  2379. X    {
  2380. X        pixel (i, i/2, 1);
  2381. X        pixel (i, 348 - i/2, 1);
  2382. X    }
  2383. X
  2384. X    waitkey();        /* wait for CR */
  2385. X
  2386. X    /* a different pattern on page 1 */
  2387. X    swpage (1);
  2388. X    for (i=0; i<720; i++)
  2389. X    for (j=0; j<348; j=j+50)
  2390. X        pixel (i,j,1);
  2391. X    for (i=0; i<720; i=i+90)
  2392. X    for (j=0; j<348; j++)
  2393. X        pixel (i,j,1);
  2394. X
  2395. X    /* switch back and forth a couple of times */
  2396. X    waitkey();
  2397. X    swpage (0);
  2398. X    waitkey();
  2399. X    swpage (1);
  2400. X    waitkey();
  2401. X    swpage (0);
  2402. X    waitkey();
  2403. X    swpage (1);
  2404. X    waitkey();
  2405. X
  2406. X#ifndef NOTONE
  2407. X    /* add some writing */
  2408. X    dline (10, 4, "Hello, there!");
  2409. X    dline (10, 5, "Second LINE of text.");
  2410. X    dline (10, 6, "all on display page 1.");
  2411. X
  2412. X    waitkey();
  2413. X    for (i=0; i<8; i++)
  2414. X        for (j=0; j<32; j++)
  2415. X            dchar (j+5, i+13, (char) (32*i+j));
  2416. X
  2417. X    waitkey();
  2418. X#endif
  2419. X    /* repeat for page 0 */
  2420. X    swpage (0);
  2421. X
  2422. X#ifndef NOTZERO
  2423. X    /* add some writing */
  2424. X    dline (10, 4, "Hello, there!");
  2425. X    dline (10, 5, "Second LINE of text.");
  2426. X    dline (10, 6, "this time on display page 0.");
  2427. X
  2428. X    waitkey();
  2429. X    for (i=0; i<8; i++)
  2430. X        for (j=0; j<32; j++)
  2431. X            dchar (j+5, i+13, (char) (32*i+j));
  2432. X#endif
  2433. X
  2434. X    waitkey();
  2435. X
  2436. X    /* back to alpha mode */
  2437. X    waitkey();
  2438. X    alfa();
  2439. X}
  2440. X
  2441. Xdline (x, y, chstr)    /* write character-string at x,y */
  2442. X    int     x,y;
  2443. X    char    chstr [90];
  2444. X{
  2445. X    int    i;
  2446. X    char    *p;
  2447. X
  2448. X    i=0;
  2449. X    for ( p=chstr; *p != '\0'; p++ )
  2450. X    {
  2451. X        dchar ( x+i, y, *p );
  2452. X        i++;
  2453. X    }
  2454. X}
  2455. SHAR_EOF
  2456. exit
  2457.